https://www.luogu.org/problemnew/show/P5444
考虑t1,t2两时刻相等的条件:t1=t2(mod B);[t1/B]=[t2/B](mod A)
可推得t2-t1=k*A/gcd(A,B+1)*B,所以循环节是A/gcd(A,B+1)*B
然后做区间并,注意要以左端点为关键字排序
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef unsigned long long ll; struct node { ll l,r; }p[2000005]; int n,cnt,i; ll A,B,l,r,w,ans; bool cmp(node a,node b) { return a.l<b.l; } ll gcd(ll a,ll b) { if(!b) return a; return gcd(b,a%b); } int main() { scanf("%d%llu%llu",&n,&A,&B); if(A/gcd(A,B+1)>1000000000000500000ll/B) w=1000000000000500000ll; else w=A/gcd(A,B+1)*B; while(n--) { scanf("%llu%llu",&l,&r); if(r-l+1>=w) { printf("%llu",w); return 0; } if(l/w==r/w) p[++cnt]=(node){l%w,r%w}; else { p[++cnt]=(node){l%w,w-1}; p[++cnt]=(node){0,r%w}; } } sort(p+1,p+1+cnt,cmp); for(i=2,l=p[1].l,r=p[1].r;i<=cnt;++i) { if(p[i].l<=r) { l=min(l,p[i].l); r=max(r,p[i].r); } else { ans+=r-l+1; l=p[i].l,r=p[i].r; } } ans+=r-l+1; printf("%llu",ans); return 0; }