• BZOJ2987:Earthquake(类欧几里德算法)


    Sol

    (n=lfloorfrac{c}{a} floor)
    问题转化为求

    [sum_{i=0}^{n}lfloorfrac{c-ax}{b} floor+1=sum_{i=0}^{n}lfloorfrac{-ax+b+c}{b} floor ]

    考虑一般性的问题

    [f(a,b,c,n)=sum_{i=0}^{n}lfloorfrac{ax+b}{c} floor,c e 0 ]

    1. (cle 0),那么 (f(a,b,c,n)=f(-a,-b,-c,n))
    2. (a<0)(b<0),那么

    [f(a,b,c,n)=f(a~mod~c + c, b~mod~c + c, c, n) + frac{n(n + 1)}{2} (lfloorfrac{a}{c} floor - 1) + (n + 1)(lfloorfrac{b}{c} floor - 1) ]

    1. (a>=c)(b>=c),那么

    [f(a,b,c,n)=f(a~mod~c, b~mod~c, c, n) + frac{n(n + 1)}{2}lfloorfrac{a}{c} floor + (n + 1)lfloorfrac{b}{c} floor ]

    1. 最后 (0le a<c)(0le b<c)
      (m=lfloorfrac{an+b}{c} floor)
      那么

    [sum_{i=0}^{n}lfloorfrac{ai+b}{c} floor=sum_{i=0}^{n}sum_{j=1}^{m}[lfloorfrac{ai+b}{c} floorge j]=sum_{i=0}^{n}sum_{j=0}^{m-1}[lfloorfrac{ai+b}{c} floorge j+1] ]

    [=sum_{i=0}^{n}sum_{j=0}^{m-1}[aige cj+c-b]=sum_{i=0}^{n}sum_{j=0}^{m-1}[ai> cj+c-b-1] ]

    [=sum_{i=0}^{n}sum_{j=0}^{m-1}[i> lfloorfrac{cj+c-b-1}{a} floor]=sum_{i=0}^{m-1}(n-lfloorfrac{ci+c-b-1}{a} floor) ]

    [=nm-sum_{i=0}^{m-1}lfloorfrac{ci+c-b-1}{a} floor=nm-f(c,c-b-a,a,m-1) ]

    边界是 (a=0) 或者 (nle 1)

    这个题直接代入就好了

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    inline ll Gcd(ll x, ll y) {
    	if (!x || !y) return x + y;
    	return !y ? x : Gcd(y, x % y);
    }
    
    inline ll Solve(ll a, ll b, ll c, ll n) {
    	if (!a) return (n + 1) * (b / c);
    	if (!n) return b / c;
    	if (n == 1) return (a + b) / c + b / c;
    	if (c < 0) return Solve(-a, -b, -c, n);
    	register ll d = abs(Gcd(Gcd(a, b), c));
    	a /= d, b /= d, c /= d;
    	if (a >= c || b >= c) return Solve(a % c, b % c, c, n) + n * (n + 1) / 2 * (a / c) + (n + 1) * (b / c);
    	if (a < 0 || b < 0) return Solve(a % c + c, b % c + c, c, n) + n * (n + 1) / 2 * (a / c - 1) + (n + 1) * (b / c - 1);
    	register ll m = (a * n + b) / c;
    	return n * m - Solve(c, c - b - 1, a, m - 1);
    }
    
    ll a, b, c, n;
    
    int main() {
    	scanf("%lld%lld%lld", &a, &b, &c), n = c / a;
    	printf("%lld
    ", Solve(-a, c + b, b, n));
        return 0;
    }
    
  • 相关阅读:
    Java语言
    包名规范
    带参数的方法
    成员变量和局部变量
    Java数据类型
    java反射机制
    JDK安装
    注释
    二维数组
    数组的经典排序
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10091774.html
Copyright © 2020-2023  润新知