$solution:$
问题其实就是求两个式子的循环节。
钦定 $t\mod B=0$且 $(t\neq 0)$,其 $t$ 为循环节。
则将 $1$ 式拆开得 $\frac{t\times (B+1)}{B}\mod A=0$。
$\frac{t\times (B+1)}{B}\equiv 0\space(\mod A)$
$\frac{t}{B}\equiv 0\space (\mod \frac{A}{gcd(A,B+1)})$
$t\equiv 0\space (\mod \frac{A\times B}{gcd(A,B+1)})$。
即循环节为 $\frac{A\times 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\n",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\n",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\n",Ans); }