codeforces C. Yet Another Counting Problem

codeforces 专栏收录该内容
246 篇文章 0 订阅

在这里插入图片描述

题目

题意:

给你 l , r l,r l,r问这个区间里面有多少个数满足 x % a % b ! = x % b % a x\%a\%b!=x\%b\%a x%a%b!=x%b%a

思路:

通过第三个例子把相等得输出后我们可以发现,相等得情况是 l c m ( a , b ) + m a x ( a , b ) lcm(a,b)+max(a,b) lcm(a,b)+max(a,b),因为 l c m lcm lcm得时候刚开模完均为 0 0 0然后以 m a x ( a , b ) max(a,b) max(a,b)为周期,然后我们就有公式 t m p 1 = ( ( r + 1 ) / l c m ∗ M a x + m i n ( ( r + 1 ) % l c m , M a x ) tmp1=((r + 1) / lcm * Max + min((r + 1) \% lcm, Max) tmp1=((r+1)/lcmMax+min((r+1)%lcm,Max) t m p 2 = l / l c m ∗ M a x + m i n ( l % l c m , M a x ) ) tmp2=l / lcm * Max + min(l \% lcm, Max)) tmp2=l/lcmMax+min(l%lcm,Max))
t m p 1 tmp1 tmp1是为了算出 r + 1 r+1 r+1前有多少个出现 x % a % b = x % b % a x\%a\%b=x\%b\%a x%a%b=x%b%a
t m p 2 tmp2 tmp2算出 l l l前有多少个出现 x % a % b = x % b % a x\%a\%b=x\%b\%a x%a%b=x%b%a
最后得 a n s = r − l + 1 − t m p 2 + t m p 1 ans=r-l+1-tmp2+tmp1 ans=rl+1tmp2+tmp1

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
typedef vector<int> veci;
typedef vector<ll> vecl;
typedef pair<int, int> pii;
template <class T>
inline void read(T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return ;
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1:1;
    ret = (c == '-') ? 0:(c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return ;
}
inline void out(int x) {
    if (x > 9) out(x / 10);
    putchar(x % 10 + '0');
}
ll gcd(ll a, ll b) {
    if (b == 0) return a;
    else return gcd(b, a % b);
}
int main() {
    ll t, a, b, q;
    read(t);
    while (t--) {
        read(a), read(b), read(q);
        ll gc = gcd(a, b);
        ll lcm = a * b / gc;
        ll Max = max(a, b);
        while (q--) {
            ll l, r;
            read(l), read(r);
            ll ans = (r - l + 1) - ((r + 1) / lcm * Max + min((r + 1) % lcm, Max) - l / lcm * Max - min(l % lcm, Max));
            printf("%lld ", ans);
        }
    }
    return 0;
}

  • 0
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值