• BZOJ 3817 Sum


    Description

    给定正整数N,R。求

    Input

    第一行一个数 T,表示有 T 组测试数据。
    接下来 T 行,每行两个正整数 n,r。

    Output

    输出 T 行,每行一个整数表示答案。

    Sample Input

    3
    3 5
    3 6
    3 7

    Sample Output

    3
    1
    -1

    HINT

    对于 100% 的数据,满足 n≤10^9,r≤10^4,T≤10^4。
    关于类欧几里得的介绍:ZYYS
    设$x=sqrt r$,则
    $$
    egin{align}
    -1^{dx } & =1-2( dx \% 2) \
    &=1-2(dx - frac{dx}{2} * 2) \
    &= 1+4frac{dx}{2} + 2 dx
    end{align}
    $$
    那么
    $$原式 =n + 4 sum_{d=1}^{n} frac{dx}{2}-2sum_{d=1}^{n}dx$$
    但系数是一个实数,写作$ans=sum_{i=1}^{n}lfloor k*i floor$
    $k=frac{a*x+b}{c}$  这里x等于根号r
    类欧的套路,将其转化为函数含义,也就是:
    函数$y=k*x$与x轴,与$x=1$和$x=n$围成的梯形有多少整点
    为了方便,这里不考虑函数线上的整点,而在开始特判(显然有整点代表x为整数)
    如果$k<1$
    那么有
    $ans=sum_{i=1}^{n}sum_{j=1}^{lfloor k*n floor}[k*i>j]$
    按照类欧的套路,移项
    $ans=sum_{i=1}^{n}sum_{j=1}^{lfloor k*n floor}[i>lfloor frac{j}{k} floor]$
    交换枚举顺序
    $ans=sum_{j=1}^{lfloor k*n floor}n-lfloor frac{j}{k} floor$
    $ans=lfloor k*n floor*n-sum_{j=1}^{lfloor k*n floor}lfloor frac{j}{k} floor$
    把$frac{1}{k}$的分母有理化,发现后面这部分可以递归
    我们发现在$k<1$递归$frac{1}{k}$时,下一个$k$会大于1,这样下一个$n$会变大
    我们可以用这个方法;
    $ans=sum_{i=1}^{n}lfloor k*i floor$
    $ans=sum_{i=1}^{n}lfloor k*i-lfloor k floor*i+lfloor k floor*i floor$
    $ans=sum_{i=1}^{n}lfloor k*i-lfloor k floor*i floor+lfloor k floor*i$
    $ans=lfloor k floor*frac{n*(n+1)}{2}+sum_{i=1}^{n}lfloor k*i-lfloor k floor*i floor$
    $lfloor k*i-lfloor k floor*i floor=lfloor frac{a*x+b-c*lfloor frac{a*x+b}{c} floor}{c} *i floor$
    把当前的$k$替换
    $k=frac{a*x+b-c*lfloor frac{a*x+b}{c} floor}{c}$
    这样$k$就小于1了
    然后按$k<1$的情况递归
    由于每次$n$都会乘以一个小于1的数,所以复杂度大概是$O(logn)$
    不过为了防止暴longlong要提出gcd,用辗转相除
    最后复杂度是$O(Tlog^{2}n)$
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long lol;
     8 double t;
     9 lol r;
    10 lol gcd(lol a,lol b)
    11 {
    12   if (!b) return a;
    13   return gcd(b,a%b);
    14 }
    15 lol cal(lol a,lol b,lol c,lol n)
    16 {
    17   if (n==0) return 0;
    18   lol g=gcd(a,gcd(b,c));
    19   a/=g;b/=g;c/=g;
    20   lol k=(t*a+b)/c;
    21   lol ans=n*(n+1)/2*k;
    22   b-=k*c;
    23   k=(t*a+b)/c*n;
    24   ans+=k*n-cal(a*c,-b*c,a*a*r-b*b,k);
    25   return ans;
    26 }
    27 int main()
    28 {int T;
    29   lol n,ans;
    30   cin>>T;
    31   while (T--)
    32     {
    33       scanf("%lld%lld",&n,&r);
    34       t=sqrt((double)r);
    35       if ((lol)t==t)
    36     {
    37       if ((lol)t%2==0)
    38         {
    39           printf("%lld
    ",n);
    40         }
    41       else
    42         {
    43           if (n%2==0)
    44         printf("0
    ");
    45           else printf("-1
    ");
    46         }
    47     }
    48       else
    49     {
    50       ans=n+(cal(1,0,2,n)<<2)-(cal(1,0,1,n)<<1);
    51       printf("%lld
    ",ans);
    52     }
    53     }
    54 }
  • 相关阅读:
    Js全选 添加和单独删除
    H5新手快速入门 简单布局
    DOM 节点 课程表
    Datalogic组网模式下通讯
    svn检出的时候报 Unable to connect to a repository at URL错误(摘自CSDN)
    Subsonic使用中
    HTTP 错误 500.21
    WinForm下增加声音提示
    IIS7.0发布Web服务器0002
    IIS7.0发布Web服务-0001
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8435828.html
Copyright © 2020-2023  润新知