题目链接:传送门
取两个不相等的整数
a
,
b
a,b
a,b,考虑什么情况下它们的
(
x
,
y
)
(x,y)
(x,y)相同:
(
a
+
⌊
a
B
⌋
)
m
o
d
A
=
(
b
+
⌊
b
B
⌋
)
m
o
d
A
(a+\lfloor\frac{a}{B}\rfloor)mod A=(b+\lfloor\frac{b}{B}\rfloor) modA
(a+⌊Ba⌋)modA=(b+⌊Bb⌋)modA
a
a
a
m
o
d
mod
mod
B
=
b
B=b
B=b
m
o
d
mod
mod
B
B
B
令
a
=
k
B
+
b
a=kB+b
a=kB+b,代入式子,大莉化简一波,发现:
a
a
a
m
o
d
mod
mod
A
B
g
c
d
(
A
,
B
+
1
)
=
b
\frac{AB}{gcd(A,B+1)} = b
gcd(A,B+1)AB=b
m
o
d
mod
mod
A
B
g
c
d
(
A
,
B
+
1
)
\frac{AB}{gcd(A,B+1)}
gcd(A,B+1)AB
所以
A
B
g
c
d
(
A
,
B
+
1
)
\frac{AB}{gcd(A,B+1)}
gcd(A,B+1)AB是一个周期。
于是问题转化为在
[
0
,
A
B
g
c
d
(
A
,
B
+
1
)
)
[0,\frac{AB}{gcd(A,B+1)})
[0,gcd(A,B+1)AB)区间内的
n
n
n条线段的交集大小。
按左端点排序一波,大莉
O
(
n
)
O(n)
O(n)求交集大小即可qwq。
要注意
A
B
g
c
d
(
A
,
B
+
1
)
\frac{AB}{gcd(A,B+1)}
gcd(A,B+1)AB过大时,把它设成
2
∗
1
0
18
2*10^{18}
2∗1018即可qwq。
代码
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
#define re register int
#define rl register ll
using namespace std;
typedef long long ll;
ll read() {
rl x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9') {
x=10*x+ch-'0';
ch=getchar();
}
return x*f;
}
inline char GetChar() {
char ch=getchar();
while(ch!='t' && ch!='q') ch=getchar();
return ch;
}
const int Size=2000005;
ll n,A,B;
struct Segment {
ll l,r;
} w[Size];
inline bool comp(Segment x,Segment y) {
if(x.l!=y.l) return x.l<y.l;
return x.r<y.r;
}
int main() {
n=read();
A=read();
B=read();
ll len=A/__gcd(A,B+1);
if(2e18/B>=len) {
len=len*B;
} else {
len=2e18;
}
int tot=0;
for(re i=1; i<=n; i++) {
ll l=read();
ll r=read();
ll tmp=r/len-l/len;
if(tmp>1) {
printf("%lld",len);
return 0;
} else if(tmp==1) {
w[++tot].l=l%len; w[tot].r=len-1;
w[++tot].l=0; w[tot].r=r%len;
} else {
w[++tot].l=l%len;
w[tot].r=r%len;
}
}
sort(w+1,w+1+tot,comp);
ll maxr=-1,ans=0;
for(re i=1; i<=tot; i++) {
if(w[i].l<=maxr) {
if(w[i].r<=maxr) continue;
ans+=w[i].r-maxr;
maxr=w[i].r;
} else {
ans+=w[i].r-w[i].l+1;
maxr=w[i].r;
}
}
printf("%lld",ans);
return 0;
}