题意:
求出区间 ([l_i,r_i]) 内满足:(((xmod a)mod b)≠((xmod b)mod a)) 的 (x) 的个数。
数据范围:$1≤a,b≤200,1≤l_i≤r_i≤10^18 $ejv
分析:
根据取模的性质,最后取模的结果会以 (lcm(a,b)) 为最小循环节进行循环,那么只要求出一个循环节内的情况,就可以求出所有的。
一开始分析的时候没有想过去暴力打表看规律,直接数学推导,发现越推越复杂。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=40010;
bool vis[N];
int init(int a,int b,int m)
{
int cnt=0;
for(int i=1;i<=m;i++)
{
int t1=i%a%b;
int t2=i%b%a;
if(t1!=t2)
{
vis[i]=1;
cnt++;
}
}
return cnt;
}
int main()
{
int t,a,b,q;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&a,&b,&q);
int lcm=a/__gcd(a,b)*b;
memset(vis,0,sizeof(vis));
int cnt=init(a,b,lcm);
while(q--)
{
ll l,r;
scanf("%lld%lld",&l,&r);
ll r1=r%lcm;
ll t1=1LL*(r/lcm)*cnt;
for(int i=1;i<=r1;i++)
{
if(vis[i])
t1++;
}
l--;
ll r2=l%lcm;
ll t2=1LL*(l/lcm)*cnt;
for(int i=1;i<=r2;i++)
{
if(vis[i])
t2++;
}
printf("%lld
",t1-t2);
}
}
return 0;
}