UOJ #42【清华集训2014】Sum

Description

给定正整数 $n,r$,求$\sum _{d=1}^n (-1)^{\lfloor \sqrt{d\times r\times d}\rfloor  }$

Solution

$$(-1)^a=1-2(a \bmod{2}) =1-2a+4\lfloor \frac{a}{2} \rfloor $$

原式化为$$n-2\sum _{i=1}^n\lfloor i\sqrt{r}\rfloor +4\sum _{i=1}^n \lfloor \frac{i\sqrt{r} }{2}\rfloor $$

类欧几里得算法计算

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int T,n,r;
long double s;
inline int read(){
    int w=0,f=1;
    char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
    return w*f;
}
long long gcd(long long a,long long b){
    if(!a||!b)return a+b;
    return b?gcd(b,a%b):a;
}
long long solve(long long a,long long b,long long c,long long len){
    if(!len)return 0;
    long long d=gcd(a,gcd(b,c));
    a/=d,b/=d,c/=d;
    long long k=(a*s+b)/c,ret=k*len*(len+1)/2;
    b-=c*k,k=(a*s+b)/c*len,ret+=k*len;
    return ret-solve(a*c,-b*c,a*a*r-b*b,k);
}
int main(){
    T=read();
    for(;T;T--){
        n=read(),r=read(),s=sqrtl(r);
        if(floor(s)*floor(s)==r)printf("%d\n",(int)s&1?-(n&1):n);
        else printf("%lld\n",1ll*n-2*solve(1,0,1,n)+4*solve(1,0,2,n));
    }
    return 0;
}
【清华集训2014】Sum

 

posted @ 2021-01-17 20:53  QDK_Storm  阅读(129)  评论(0编辑  收藏  举报