题意:
给你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;
}