$solution:$
问题其实就是求两个式子的循环节。
钦定 $tmod B=0$且 $(t eq 0)$,其 $t$ 为循环节。
则将 $1$ 式拆开得 $frac{t imes (B+1)}{B}mod A=0$。
$frac{t imes (B+1)}{B}equiv 0space(mod A)$
$frac{t}{B}equiv 0space (mod frac{A}{gcd(A,B+1)})$
$tequiv 0space (mod frac{A imes B}{gcd(A,B+1)})$。
即循环节为 $frac{A imes B}{gcd(A,B+1)}$
直接做线段覆盖即可。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define int long long using namespace std; inline int read(){ int f=1,ans=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } const int MAXN=1000001; int n,A,B,k; int gcd(int a,int b){ if(!b) return a; return gcd(b,a%b); } struct node{ int l,r; }x[MAXN<<1]; int cnt,Ans; bool cmp(node x1,node x2){return x1.l<x2.l;} void debug(){ for(int i=1;i<=cnt;i++) printf("l:%d r:%d ",x[i].l,x[i].r); return; } signed main(){ // freopen("make.in","r",stdin); n=read(),A=read(),B=read(); k=(A/gcd(A,B+1))*B; for(int i=1;i<=n;i++){ int l=read(),r=read(); if((r-l+1)>=k){printf("%lld ",k);return 0;} if(l==r){x[++cnt].l=l%k,x[cnt].r=l%k;continue;} if((l%k)<=(r%k)){x[++cnt].l=l%k,x[cnt].r=r%k;continue;} else{ x[++cnt].l=l%k,x[cnt].r=k-1; x[++cnt].l=0,x[cnt].r=r%k; } } sort(x+1,x+cnt+1,cmp); int L=x[1].l,R=x[1].r; for(int i=2;i<=cnt;i++){ if(x[i].l>R){Ans+=R-L+1;L=x[i].l,R=x[i].r;continue;} R=max(R,x[i].r); }Ans+=R-L+1; printf("%lld ",Ans); }