[HDU 4790 Just Random]同余统计

题目

http://acm.hdu.edu.cn/showproblem.php?pid=4790

分析

在[a,a+p-1]、[a+p,a+2*p-1]、...  与[c,c+p-1]、[c+p,c+2*p-1]...这些区间之间,直接乘法原理计算即可。

现在只考虑 [a',b]   [c',d]这些区间中的答案。  将[a',d]所配对的答案区间[A,B]求出

这时只要看[A,B]与[c',d]的交集大小即可。

代码


#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<string.h>

using namespace std;
typedef long long int64;
int64 a,b,c,d,p,m,dd,ans,fm;
int T,test;
int64 work(int64 l1,int64 r1,int64 l2,int64 r2)
{
    if(l1>r1||l2>r2) return 0;
    int64 ll=(p+m-r1)%p,rr=(p+m-l1)%p;
    r2=(r2-l2+p)%p; ll=(ll-l2+p)%p; rr=(rr-l2+p)%p;
    if(ll<=rr)
    {
        if(r2<ll) return 0;
        return min(r2,rr)-ll+1;
    }
    int64 res=min(rr,r2)+1;
    res+=(r2-ll+1);
    return res;
}
int main()
{
//   freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&p,&m);
        int l=a,r=b-(b-a+1)/p*p;
        int ll=c,rr=d-(d-c+1)/p*p;
        ans=(b-a+1)*((d-c+1)/p)+(d-c+1)*((b-a+1)/p)-((d-c+1)/p*p)*((b-a+1)/p);
        ans=ans+work(l,r,ll,rr);
        fm=(b-a+1)*(d-c+1);
        dd=__gcd(fm,ans);
        ans/=dd; fm/=dd;
        printf("Case #%d: %I64d/%I64d\n",++test,ans,fm);
    }
    return 0;
}


你可能感兴趣的:([HDU 4790 Just Random]同余统计)