hdu4790 Just Random (数学?)
acm.hdu.edu.cn/showproblem.php?pid=4790
题意:x随机取a~b,y随机取c~d,求(x+y)mod p = m 的概率。(结果用分数表示)
题解:
数学概率题,运用到了一般的概率姿势。
要求z=x+y的概率,可以先算符合条件的x的个数,可以由x和y的范围列出2个不等式,用min和max表示得出x的个数。
这样概率就是x的个数/ ((b-a+1)(d-c+1))。
我们要求一大堆这种z的和。
搞一搞发现是等差数列求和+一堆和+等差数列求和。
可以画到二维坐标系上更直观,x和y在一个矩形范围,x+y=z是一根斜线,求各种符合mod p =m的z斜线在范围内经过的总点数,也是两个等差求和 + 一个那啥求和。
总之好像是很水的数学题的样子,我还想了好久才写出来。
//#pragma commen(linker,"/STACK:1024000000,1024000000") #include<cstring> #include<iostream> #include<cstdio> #include<vector> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstdlib> #include<string> #include<list> #include<sstream> #include<set> #include<map> using namespace std; #define type int #define ll long long #define maxm 2000500 #define re freopen("in.txt","r",stdin) #define we freopen("out.txt","w",stdout) #define pi acos(-1.0) #define mod (1000000007) #define inf 0x7fffffff #define maxn 100006 #define pb push_back ll a,b,c,d,p,m; ll ans0,ans1; void farm(){ ll i,j,k; ll f1,f2,biu; if(b+c < a+d){ f1=b+c; f2=a+d; biu=b-a+1; }else{ f1=a+d; f2=b+c; biu=d-c+1; } i=(a+c-m)/p; ll z=i*p+m; if(z<a+c){ z+=p; i++; } ans0=0;ans1=1; if(z>b+d)return; ans1=(b-a+1) * (d-c+1); if(z<=f1){ j=(f1-m)/p; k=j*p+m; ans0 += (z-c-a+1 + k-c-a+1)*(j-i+1)/2; i=j+1; z=k+p; } if(z<=f2){ j=(f2-m)/p; k=j*p+m; ans0 += biu*(j-i+1); i=j+1; z=k+p; } if(z<=b+d){ j=(b+d-m)/p; k=j*p+m; ans0 += (b-z+d+1 + b-k+d+1)*(j-i+1)/2; i=j+1; z=k+p; } if(ans0==0){ ans1=1; return; } ll gcd=__gcd(ans0,ans1); ans0/=gcd; ans1/=gcd; return; } int main() { int T,cas=1; //re; scanf("%d",&T); while(T--){ scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&p,&m); farm(); printf("Case #%d: %I64d/%I64d\n",cas++,ans0,ans1); } return 0; }