CodeForces - 1342C Yet Another Counting Problem (数论)

CodeForces - 1342C Yet Another Counting Problem (数论)

题目大意:给定一个区间以及两个正整数a,b,求这个区间内满足 ( ( x   m o d   a )   m o d   b ) ≠ ( ( x   m o d   b )   m o d   a ) ((x \space mod \space a) \space mod \space b)\neq((x\space mod \space b)\space mod \space a) ((x mod a) mod b)=((x mod b) mod a)的正整数x的数量。
题解:正难则反。我们可以考虑先计算这个区间内有多少满足 ( ( x   m o d   a )   m o d   b ) = ( ( x   m o d   b )   m o d   a ) ((x \space mod \space a) \space mod \space b)=((x\space mod \space b)\space mod \space a) ((x mod a) mod b)=((x mod b) mod a)的正整数x。不妨设 a ≤ b a \leq b ab,则有:
x   m o d   a = ( ( x   m o d   b )   m o d   a ) x ≡ ( x   m o d   b )   m o d   a x \space mod \space a=((x\space mod \space b)\space mod \space a)\\x\equiv (x \space mod \space b)\space mod \space a x mod a=((x mod b) mod a)x(x mod b) mod a
x = k b + r , d = g c d ( a , b ) x=kb+r,d=gcd(a,b) x=kb+r,d=gcd(a,b)
k b + r ≡ r   m o d   a k b ≡ 0   m o d   a k ∗ ( b / d ) ≡ 0   m o d   ( a / d ) k ≡ 0   m o d   ( a / d ) kb+r\equiv r\space mod \space a\\kb\equiv 0 \space mod \space a\\k*(b/d)\equiv 0\space mod \space (a/d)\\k\equiv0\space mod \space (a/d) kb+rr mod akb0 mod ak(b/d)0 mod (a/d)k0 mod (a/d)
问题即转化为:给定一个区间[l,r],存在某类数除以b得到的商可以整除(a/d),设这类数的数量为y,求r-(l-1)-y。我们可以进一步简化问题为:如果有函数cal(x)可以给出关于区间[1,x]的这个问题的答案,那么我们只需要输出cal(r)-cal(l-1)的结果即可。
下面是AC代码。

#include<bits/stdc++.h>
using namespace std;
struct fastio{fastio(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}}fio;
#define int long long
#define debug(x) cerr<<#x<<":"<<x<<endl
#define endl '\n'
signed main(){
    int t,a,b,q,l,r;
    cin>>t;
    while(t--){
        cin>>a>>b>>q;
        if(a>b) swap(a,b);
        int ap=a/__gcd(a,b);
        auto cal=[=](int n)->int{
            int k=n/b;
            if(k%ap==0) return n-((k/ap)-1)*b-n%b-1;
            return n-(k/ap)*b;
        };
        while(q--){
            cin>>l>>r;
            cout<<cal(r)-cal(l-1)<<" ";
        }
        cout<<endl;
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值