hdu 4790 Just Random

题意:

给你a,b,c,d,p,m,从区间[a,b]任意选一个数x从区间[c,d]任意选一个数y满足(x+y)%p= m 的概率是多少

方法:

对[a,a],[c,d]: 可以快速算出至少有(d-c+1)/m 个满足条件的x.y

同理对[a,b][c,d]可以得到至少有(b-a+1)*(d-c+1)/m个

对[a,a][c,d]区间还剩下t= (d-c+1)%m 个数没有计算,区间[a,b][c,d]就还剩下(b-a+1)*t个数没讨论,然后我们根据每个区间%m的第一个数会呈现0,1,2,3,4,5,6,7,,m-1,0,1的变化去统计即可

PS:

我说不清楚。。。 表达能力有限

 

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL __int64

LL gcd(LL a, LL b)
{
	return b== 0? a: gcd(b, a%b);			
}

int main()
{
//	freopen("in.txt","r",stdin);
	int T; scanf("%d",&T);
	for(int C= 1; C<= T; C++)
	{
		LL a, b, c, d, p, m;
		scanf("%I64d %I64d %I64d %I64d %I64d %I64d", &a, &b, &c, &d, &m, &p);
		LL ans= (d- c+ 1)/m;
		ans*= (b- a+ 1);
		int t= (d- c+ 1)%m;
		//首个数 
	//	printf("%I64d\n", ans);
		if(t)
			ans+= ((b- a+ 1)/m)*(t);
	//	printf("%I64d\n", ans);
		int xx= (b- a+ 1)%m;
		//int xx= (d- c+ 1)%m;
		int num= (a + c)%m;
		int z;
	//	printf("num= %d p= %d\n",num, p);
		if(num<= p)
			z= p- num;
		else
			z= (p+1)+ (m- 1- num);
	//	printf("%d %d\n",z,xx);
		if(z+1>= xx)
		{
			int ll= z-xx+1, rr= z;
			ll++, rr++;
	//		printf("%d %d\n", ll,rr);
			if(t>= ll)
			{
				if(t>= rr)
					ans+= rr- ll +1;
				else
					ans+= t- ll +1;	
			}
		}	
		else
		{
			int ll= 0, rr= z;
			ll++, rr++;
	//		printf("%d %d %d\n",ll,rr,t);
			if(t>= rr)
				ans+= rr- ll+1;
			else
				ans+= t- ll+1;
			xx-= z+1;
			ll= (m-1)-xx+1, rr= m-1;
			ll++, rr++;
	//		printf("%d %d %d\n",ll,rr,t);
			if(t>= ll)
			{
				if(t>= rr)
					ans+= rr-ll+1;
				else
					ans+= t-ll+1;	
			}		
		}
	//	printf("%I64d\n",ans);	
		printf("Case #%d: ",C);
		if(ans== 0)
			printf("0/1\n");
	//		printf("0\n");
		else
		{
			LL sum= (d-c+1)*(b-a+1);
			LL g= gcd(ans,sum);
			printf("%I64d/%I64d\n",ans/g,sum/g); 
		//	printf("%lf\n",1.0*ans/sum);
		}	
	}
	return 0;
}


 

 

你可能感兴趣的:(hdu 4790 Just Random)