HDU 4790 (大模拟)

瞎搞。
把A分成P+P+…+P+lA~rA段
把B分成l1Br1B+P+P+…+P+l2Br2B段
A中有xA段P,B中有yB段P,两个长度为P的区间会产生P对,所以整数段将产生 x A y B p xA*yB*p 这么多种组合。其余三段分情况讨论。(有可能B产生的分段不足P且在P分段之间,情况复杂,需耐心讨论)

#include <bits/stdc++.h>
using namespace std;
#define _int long long

_int a,b,c,d,p,m,B1,B2;
_int xA,yB;
_int lA,rA,l1B,r1B,l2B,r2B;
_int ans;
_int gcd(_int a,_int b){
    if (a==0 || b==0) return a+b;
    return gcd(b,a%b);
}
int fun(){
    ans=0;
    if (r1B-l1B > rA-lA){
        ans = ans + (rA-lA)*(xA+1);
        ans = ans + ((r1B-l1B)-(rA-lA))*(xA);
    }
    else ans = ans + (r1B-l1B)*(xA+1);

    if ((r2B-l2B) > p-(rA-lA)){
        ans = ans + (p-(rA-lA))*(xA);
        ans = ans + ((r2B-l2B)-(p-(rA-lA)))*(xA+1);
    }
    else ans = ans + (r2B-l2B)*(xA);

    ans = ans + (rA-lA) * (yB) ;
    ans = ans + xA*yB*p;
    return 0;
}
int main(){
    _int T,Case=1;
    scanf("%I64d",&T);
    while (T--){
        printf("Case #%I64d: ",Case++);
        scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&d);
        scanf("%I64d%I64d",&p,&m);

        ///part 0
        c=c+p-m;
        d=d+p-m;
        _int fenmu=(b-a+1)*(d-c+1);

        ///part 1  确定B1
        B1=(p-(a%p))%p;
        if (B1<=d) B1=B1+(d-B1)/p*p;
        while (B1<=d) B1=B1+p;
        B1=B1-p;
        B2=B1;
        if (B2>=c) B2=B2-(B2-c)/p*p;
        while (B2>=c) B2=B2-p;
        B2=B2+p;

        ///part 2 找到A区间有多少P段长度 --> XA
        ///       找到B区间有多少P段长度 --> XB
        xA=(b+1-a)/p;
        yB=(B1+1-c)/p;

        ///part 3 找到A的x+1区间左闭右开[x,y); 和B的两段y+1区间 左开右闭->左闭右开
        lA=0;
        rA=(b-a+1)%p;

        l1B=p-(B2-c);
        if (l1B==1) l1B=p+1;
        r1B=p+1;

        l2B=1;
        r2B=(d-B1)%p+1;
        if (B1 > d || B1 < c){
            _int fa=p-c%p,ffa=fa,ffb,xx1,xx2,fffa,fffb,fff;

            if (fa<a) ffa=fa+(a-fa)/p*p;
            ffa=ffa-p-p;
            while (ffa<a) ffa=ffa+p;
            ffb=ffa-(d-c);
            xx1=max(ffb,a);
            xx2=min(ffa,b);

            fffa=xx1;
            if (fffa<b) fffa=fffa+(b-fffa)/p*p;
            fffa=fffa-p-p;
            while (fffa<=b) fffa=fffa+p;
            fffa=fffa-p;
            fffb=fffa+(xx2-xx1);
            fff=min(b,fffb);

            ans=(xx2-xx1+1)*((b-xx1)/p)+fff-fffa+1;
            if (ans < 0){
                printf("0/1\n");
                continue;
            }
            _int anssg;
            anssg=gcd(ans,fenmu);
            if (anssg==0) anssg=1,fenmu=1;
            printf("%I64d/%I64d\n",ans/anssg,fenmu/anssg);
            continue;
        }
        fun();
        _int anssg;
        anssg=gcd(ans,fenmu);
        if (anssg==0) anssg=1,fenmu=1;
        printf("%I64d/%I64d\n",ans/anssg,fenmu/anssg);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/aiaidexiaji/article/details/71124009