[luogu5172 Sum

luogu5172 Sum

[egin{aligned} sum_{d=1}^n(-1)^{lfloor dsqrt r floor}=&sum_{d=1}^n(-1)^{lfloor dsqrt r floor mod 2}\ =&sum_{d=1}^n1-2(lfloor dsqrt r floor mod 2)\ =&n-sum_{d=1}^n2(lfloor dsqrt r floor-2lfloorfrac{lfloor dsqrt r floor}{2} floor)\ =&n+4sum_{d=1}^nlfloorfrac{dsqrt r}{2} floor-2sum_{d=1}^nlfloor dsqrt r floor end{aligned} ]

将问题一般化,记(x=sqrt r),其实我们求的是

[sum_{i=1}^n lfloor frac{ax+b}{c} i floor ]

我们再记(frac{ax+b}{c}=k),最后就是求

[sum_{i=1}^n lfloor ki floor ]

仿照类欧的思想分类讨论

(1)若(kgeq 1)

[egin{aligned} sum_{i=1}^n lfloor ki floor=&sum_{i=1}^nlfloor ki-lfloor k floor i+lfloor k floor i floor\ =&sum_{i=1}^nlfloor ki-lfloor k floor i floor+frac{n(n+1)}{2}lfloor k floor\ =&sum_{i=1}^n lfloor frac{ax+b-clfloor frac{ax+b}{c} floor*i}{c} floor+lfloor k floor * frac{n(n+1)}{2} end{aligned} ]

(2)若(k<1),继续考虑其几何意义

[egin{aligned} sum_{i=1}^n lfloor ki floor=&sum_{i=1}^nsum_{j=1}^{lfloor k*n floor} [k*i>j]\ =&sum_{i=1}^nsum_{j=1}^{lfloor k*n floor} [i>frac{j}{k}]\ =&sum_{j=1}^{lfloor k*n floor}sum_{i=1}^n [i>frac{j}{k}]\ =&sum_{j=1}^{lfloor k*n floor} (n-lfloor frac{j}{k} floor)\ =&lfloor k*n floor*n-sum_{j=1}^{lfloor k*n floor}lfloor frac{j}{k} floor end{aligned} ]

注意到使用(2)的时候需要k是一个无理数,所以预处理(r)是奇数时需要特判,同时递归时需要分母有理化

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
ll n,r;
double x;
int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}  

ll gcd(ll x,ll y)
{
    if ((!x) || (!y)) return x+y;
    else return gcd(y,x%y);
}

ll solve(ll a,ll b,ll c,ll n)
{
    if (!n) return 0;
    if (n==1) return (a*x+b)/c;
    ll g=gcd(gcd(a,b),c);
    a/=g;b/=g;c/=g;
    ll k=(a*x+b)/c;
    if (k!=0)
    {
        return k*n*(n+1)/2+solve(a,b-c*k,c,n);
    }
    else 
    {
        ll tmp=(a*x+b)/c*n;
        return tmp*n-solve(a*c,-b*c,a*a*r-b*b,tmp);
    }
}

int main()
{
    int T=read();
    while (T--)
    {
        n=read();r=read();
        x=sqrt((double)r);ll tmp=(ll)x;
        if (tmp*tmp==r)
        {
            if (tmp&1) printf("%lld
",n-2*((n+1)>>1));
            else printf("%lld
",n);
        }
        else printf("%lld
",n-solve(1,0,1,n)*2+solve(1,0,2,n)*4);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/encodetalker/p/11048683.html