码迷,mamicode.com
首页 > 其他好文 > 详细

[luogu5172 Sum

时间:2019-06-19 00:19:03      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:pac   owb   new   cpp   注意   cto   a*   show   define   

luogu5172 Sum

\[ \begin{aligned} \sum_{d=1}^n(-1)^{\lfloor d\sqrt r\rfloor}=&\sum_{d=1}^n(-1)^{\lfloor d\sqrt r\rfloor\ mod\ 2}\=&\sum_{d=1}^n1-2(\lfloor d\sqrt r\rfloor\ mod\ 2)\=&n-\sum_{d=1}^n2(\lfloor d\sqrt r\rfloor-2\lfloor\frac{\lfloor d\sqrt r\rfloor}{2}\rfloor)\=&n+4\sum_{d=1}^n\lfloor\frac{d\sqrt r}{2}\rfloor-2\sum_{d=1}^n\lfloor d\sqrt r\rfloor \end{aligned} \]

将问题一般化,记\(x=\sqrt r\),其实我们求的是
\[ \sum_{i=1}^n \lfloor \frac{ax+b}{c} i \rfloor \]
我们再记\(\frac{ax+b}{c}=k\),最后就是求
\[ \sum_{i=1}^n \lfloor ki \rfloor \]

仿照类欧的思想分类讨论

(1)若\(k\geq 1\)
\[ \begin{aligned} \sum_{i=1}^n \lfloor ki\rfloor=&\sum_{i=1}^n\lfloor ki-\lfloor k\rfloor i+\lfloor k\rfloor i \rfloor\=&\sum_{i=1}^n\lfloor ki-\lfloor k\rfloor i\rfloor+\frac{n(n+1)}{2}\lfloor k\rfloor\=&\sum_{i=1}^n \lfloor \frac{ax+b-c\lfloor \frac{ax+b}{c} \rfloor*i}{c}\rfloor+\lfloor k\rfloor * \frac{n(n+1)}{2} \end{aligned} \]

(2)若\(k<1\),继续考虑其几何意义
\[ \begin{aligned} \sum_{i=1}^n \lfloor ki\rfloor=&\sum_{i=1}^n\sum_{j=1}^{\lfloor k*n\rfloor} [k*i>j]\=&\sum_{i=1}^n\sum_{j=1}^{\lfloor k*n\rfloor} [i>\frac{j}{k}]\=&\sum_{j=1}^{\lfloor k*n\rfloor}\sum_{i=1}^n [i>\frac{j}{k}]\=&\sum_{j=1}^{\lfloor k*n\rfloor} (n-\lfloor \frac{j}{k}\rfloor)\=&\lfloor k*n\rfloor*n-\sum_{j=1}^{\lfloor k*n\rfloor}\lfloor \frac{j}{k}\rfloor \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",n-2*((n+1)>>1));
            else printf("%lld\n",n);
        }
        else printf("%lld\n",n-solve(1,0,1,n)*2+solve(1,0,2,n)*4);
    }
    return 0;
}

[luogu5172 Sum

标签:pac   owb   new   cpp   注意   cto   a*   show   define   

原文地址:https://www.cnblogs.com/encodetalker/p/11048683.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!