zoukankan      html  css  js  c++  java
  • @51nod


    @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 imes A + q imes B),其中 (0 leq p < B)

    因此我们枚举 p,得到 [0...N] 可被覆盖的数的数量:

    [sum_{p=0}^{B-1且p imes A leq N}(lfloorfrac{N - p imes A}{B} floor + 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
    ", get(A, B, Y) - get(A, B, X));
    }
    
    int main() {
    	int T; scanf("%d", &T);
    	while( T-- ) solve();
    }
    

    @details@

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

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

  • 相关阅读:
    js压缩图片上传插件localResizeIMG
    valueOf函数详解
    垂直居中
    word-wrap,word-break,white-space
    理解bind函数
    float失效的情况
    塞码考试系统里的输入,到底是怎么回事
    理解position:relative
    border实现三角形的原理
    函数是对象,函数名是指针
  • 原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/12448112.html
Copyright © 2011-2022 走看看