Yet Another Counting Problem-CF 1342C

题意:

求出区间 ([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;
}

原文地址:https://www.cnblogs.com/1024-xzx/p/12817091.html