清华集训2014 sum

Posted tyher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清华集训2014 sum相关的知识,希望对你有一定的参考价值。

  • 清华集训2014sum
  • [∑_{i=1}^{n}(-1)^{?i√r?}]
  • 多组询问,(nleq 10^9,tleq 10^4, rleq 10^4)
  • 吼题解啊
  • 具体已经讲得很详细了(找了好久才找到的良心题解。)
  • 首先看到向下取整的式子要会拆开。
  • 然后套类欧几里德。
  • 这里的类欧几里德比较简单,因为可以看作是(y=kx)的正比例的向下整点。
  • 如果(k>1),那么就相当与直接算上面的点,然后把直线砍到(kleq 1)
  • 否则取反函数,相当于减小了(n)而增大了(k)
  • 这样每次一定会缩小一半的问题规模,复杂度是(O(logn))的。
#include<bits/stdc++.h>
#define R register int
#define ll long long
#define db double
using namespace std;
int T;ll n,r,ans,t;db q;
int gi(){
    R x=0,k=1;char c=getchar();
    while(c!=‘-‘&&(c<‘0‘||c>‘9‘))c=getchar();
    if(c==‘-‘)k=-1,c=getchar();
    while(c<=‘9‘&&c>=‘0‘)x=(x<<3)+(x<<1)+c-‘0‘,c=getchar();
    return x*k;
}
ll Gcd(ll x,ll y){return y?Gcd(y,x%y):x;}
ll sol(ll a,ll b,ll c,ll n){
    if(n==1)return (a*q+b)/c;
    if(n==0)return 0;
    ll gcd=Gcd(a,Gcd(b,c));
    a/=gcd,b/=gcd,c/=gcd;
    ll k=(a*q+b)/c;
    if(k==0){
        ll m=((a*q+b)/c*n);
        return m*n-sol(a*c,-b*c,a*a*r-b*b,m);
    }
    else return k*(n*(n+1)/2)+sol(a,b-c*k,c,n);
}

void cheat(){
    if(!(t&1))printf("%lld
",n);
    else if(n&1)puts("-1");
    else puts("0");
}
int main(){
    T=gi();
    while(T--){
        n=gi(),r=gi(),q=sqrt(r),t=q;
        if(t*t==r){cheat();continue;}
        ans=n+4ll*sol(1,0,2,n)-2ll*sol(1,0,1,n);
        printf("%lld
",ans);
    }
    return 0;
}

以上是关于清华集训2014 sum的主要内容,如果未能解决你的问题,请参考以下文章

uoj#37/bzoj3812[清华集训2014]主旋律 状压dp+容斥原理

线性基 uoj 36 清华集训2014 玛里苟斯

UOJ#36. 清华集训2014玛里苟斯 线性基

AC日记——清华集训2014奇数国 uoj 38

Loj #6703 -「清华集训 2017」生成树计数

UOJ#46. 清华集训2014玄学