CodeChef - ZUBRIDER Club of Riders 数学 组合数

At a shopping mall, every now and then, a naughty kid steals some chocolates from different chocolate shops and runs away. The guards in the shopping mall were unable to catch the kid as he has got a fast scooter.

Each scooter has a performance value. Also, this kind of scooter needs a skilled rider to perform well. The total performance of a rider is measured by the value of scooter performance multiplied by rider’s skill. A rider X can catch a rider Y only if X’s total performance is more than Y’s.The shopping mall manager has bought one scooter for each guard. However, as he has bought them from an wholesale offer, their performance values need not be the same.

Each guard gets a scooter and of course, a scooter can be assigned to only one guard. Now, the manager wants to assign the scooters to the guards. Everyday the guards are on duty in different places and that's why each has to be able to catch the kid and only then an assignment will be valid.

So in short, given the skill of that kid, his scooter’s performance value, each guard’s skill, and each scooter’s performance value, find out the number of valid assignments possible. In a valid assignment, each guard will be able to catch the kid. As the result can be very large, find the mod 109 + 7 of the result.

Input

Output

For each test case, print "Case i: ", and then the answer (mod 109 + 7), where i is the testcase number, 1-indexed.

Constraints

Example

Input:
2
2 3
3
3 1 3
7 3 4
2 3
3
3 1 3
2 7 4

Output:
Case 1: 2
Case 2: 0

Explanation

Testcase 1: The valid arrangements are the following:

Testcase 2: There is no valid arrangement.

  • The first line of the input contains an integer T denoting the number of test cases. The description of each test case follows.
  • The first line of each test case contains two integers Kp and Ks denoting the kid's performance value and his scooter's performance value respectively.
  • The next line contains a single integer N denoting the number of guards.
  • The third line contains N integers G1, G2, G3, ... , GN denoting the performance values of the guards.
  • The fourth line of each test case contains N integers S1, S2, S3, ... , SNdenoting the performance values of the scooters.
    • 1 ≤ T ≤ 10
    • 1 ≤ N, Kp, Ks, Gi, Si ≤ 106
    • [1st guard, 2nd scooter], [2nd guard, 1st scooter], [3rd guard, 3rd scooter]
    • [1st guard, 3rd scooter], [2nd guard, 1st scooter], [3rd guard, 2nd scooter]

题意:给出KP,KS, n,接下来给出两行,每行n个数,第一行G数组和第二行S数组的数两两搭配,要求乘积大于KP*KS,问有多少种组合方式

题解:我们将,G数组和S数组从小到大排序,在S数组中从小到大,找G数组中符合的数,因为在S中我们是从小到大找的,所以,后找的符合的范围一定大于等于先找的符合的范围,因此,若在找第k个数时,符合条件的位w个,那么可选的就为w - (k - 1),若w-(k-1) 小于等于0了,也就没有符合的搭配了。定义一个变量标记S数组可行的位置,复杂度 O(n) 

#include<iostream>
#include<cstdio>
#include<algorithm>
typedef long long ll;
using namespace std;
const int N=1e6+10;
const ll mod=1e9+7;
int n;
ll k,g;
ll G[N],S[N];
int main()
{
	int T;
	int nn=1;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%lld%lld",&k,&g);
		scanf("%d",&n);
		for(int i=1;i<=n;i++)scanf("%lld",&G[i]);
		for(int i=1;i<=n;i++)scanf("%lld",&S[i]);
		sort(G+1,G+1+n);
		sort(S+1,S+1+n);
		ll ans=1;
		k=k*g;
		int flag=0;
		ll pos=n;
		for(int i=1;i<=n;i++)
		{
			while(pos>=1&&G[pos]*S[i]>k)
			{
				pos--;
			}

			if(n-pos-(i-1) <= 0)
			{
				flag=1;
				break;
			}
			ans = ans * (n - pos - i + 1) % mod;
		}
		printf("Case %d: ",nn++);
		if(flag) printf("0\n");
		else 
		printf("%lld\n",ans);
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/85109399