ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

@51nod - 1132@ 覆盖数字的数量 V2

2020-03-09 12:55:04  阅读:292  来源: 互联网

标签:... return 覆盖 51nod 1132 ll times V2 func


目录


@description@

给出2个整数A,B。可以使用任意次。再给出一段从X - Y的区间T,任选若干个A,B做加法,可以覆盖区间T中多少个不同的整数。
例如:A = 8,B = 11,区间T为3 - 20。在3 - 20中,整数8(8),11(11),16(8+8),19(8+11)。可以被区间S中的数覆盖,因此输出4。

原题传送门。

@solution@

首先变成 A,B 在 [0...r] 覆盖的数减去 A,B 在 [0...l-1] 覆盖的数。问题变成求 A,B 在 [0...N] 覆盖的数。

然后 A, B, N 同时除以 gcd(A, B),不过 N 可能不能整除,此时向下取整。

当 A, B 互质时,某数 X 一定可以表示为 \(p\times A + q\times B\),其中 \(0 \leq p < B\)。

因此我们枚举 p,得到 [0...N] 可被覆盖的数的数量:
\[\sum_{p=0}^{B-1且p\times A \leq N}(\lfloor\frac{N - p\times A}{B}\rfloor + 1)\]

这是一个经典的类欧几里得。直接做即可。

@accepted code@

#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;

ll gcd(ll x, ll y) {return (y == 0 ? x : gcd(y, x % y));}

ll func(ll n, ll a, ll b, ll c) {
    if( a >= c ) return func(n, a % c, b, c) + (a/c)*n*(n + 1)/2;
    if( b >= c ) return func(n, a, b % c, c) + (b/c)*(n + 1);
    ll m = (a * n + b) / c;
    if( a == 0 || m == 0 ) return 0;
    return n*m - func(m - 1, c, c - b - 1, a);
}

ll get(ll A, ll B, ll N) {
    ll p = min(N / A, B - 1);
    return func(p, A, N - p*A, B) + p;
}
void solve() {
    ll A, B, X, Y; scanf("%lld%lld%lld%lld", &A, &B, &X, &Y), X--;
    ll d = gcd(A, B); A /= d, B /= d, X /= d, Y /= d;
    
    printf("%lld\n", get(A, B, Y) - get(A, B, X));
}

int main() {
    int T; scanf("%d", &T);
    while( T-- ) solve();
}

@details@

关于 A, B 互质时的覆盖 —— 想起「小凯的疑惑」。

基本上算是个类欧板子题吧。

标签:...,return,覆盖,51nod,1132,ll,times,V2,func
来源: https://www.cnblogs.com/Tiw-Air-OAO/p/12448112.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有