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 $$
类欧几里得算法计算
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }