“类欧几里得算法”第一题 sum

【题意】

给入\(n,r\),求\(\sum_{d=1}^n(-1)^{\lfloor d\sqrt r \rfloor}\)。

【分析】

只需要考虑所有\(d\)中,\(\lfloor d\sqrt r\rfloor\)为偶数的个数。显然\(\lfloor x\rfloor\)为偶数\(\Leftrightarrow \lfloor x\rfloor=2\times\lfloor\frac{x}{2}\rfloor\)。 那么原式可以改写为:

\[\sum_{d=1}^n 1-2\times(\lfloor d\sqrt r\rfloor\bmod 2)=\sum_{d=1}^n 1-2\times(\lfloor d\sqrt r\rfloor-2\times\lfloor\frac{d\sqrt r}{2}\rfloor)\\
=n-2\times\sum_{d=1}^n\lfloor d\sqrt r\rfloor+4\times\sum_{d=1}^n\lfloor\frac{d\sqrt r}{2}\rfloor
\]

不妨设\(f(a,b,c,n)=\sum_{d=1}^n\lfloor d\times\frac{a\sqrt r+b}{c}\rfloor\),那么原式即为

\[n-2\times f(1,0,1,n)+4\times f(1,0,2,n)
\]

考虑关于\(f(a,b,c,n)\)的算法,(开始扣题了),设\(k=\frac{a\sqrt r +b}{c}\)。

当\(k\ge1\)时,\(k\)可以拆为一个正数+小于1的非负实数,即

\[f(a,b,c,n)=\sum_{d=1}^n \lfloor d\times k\rfloor=\sum_{d=1}^n d\times\lfloor k\rfloor+\lfloor d\times(k-\lfloor k\rfloor)\rfloor\\
=\frac{n(n+1)}{2}\lfloor k\rfloor+\sum_{d=1}^n\lfloor d\times\frac{a\sqrt r+b-\lfloor k\rfloor\times c}{c}\rfloor\\
=\frac{n(n+1)}{2}\lfloor k\rfloor+f(a,b-\lfloor k\rfloor\times c,c,n)
\]

当\(k<1\)时,(比如上面递归的那层),可以看作是满足

\[\begin{cases}
0<x\le n\\
0<y\le x\times k\\
x\in Z\\
y\in Z
\end{cases}
\]

的点数。考虑再矩形\((1,1)(n,\lfloor n\times k\rfloor)\)内容斥可得个数为\(n\times\lfloor n\times k\rfloor\) 减去左上三角的部分,而那部分可当作是\(y=x\times k,\ x\in[1,n]\)的反函数\(y=x\times \dfrac{1}{k}, x\in[1,\lfloor n\times k\rfloor]\)。

其中\(\dfrac{1}{k}=\dfrac{c}{a\sqrt r+b}=\dfrac{c(a\sqrt r-b)}{(a\sqrt r+b)(a\sqrt r-b)}=\dfrac{ac\sqrt r-bc}{a^2r-b^2}\)。

\[f(a,b,c,n)=n\times\lfloor n\times k\rfloor-f(ac,-bc,a^2r-b^2,\lfloor n\times k\rfloor)
\]

可以发现,情况一二交替递归,且每轮的总的变化与欧几里得算法相似,故知其复杂度为\(\log​\)级的。

难度海星。。

然而当\(r\)为完全平方数时需要单独算,大概会爆LL吧。。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL n,r;
double x;
LL f(LL a,LL b,LL c,LL n) {
if(!n) return 0;
LL d=__gcd(__gcd(a,b),c);
a/=d, b/=d, c/=d;
double k=(a*x+b)/c;
if(k>=1) return n*(n+1)/2*(LL)(k)+f(a,b-(LL)(k)*c,c,n);
else return n*(LL)(n*k)-f(a*c,-b*c,a*a*r-b*b,(LL)(n*k));
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%lld%lld",&n,&r);
x=sqrt(r);
LL c=x;
if(c*c==r) {
if(c&1) printf("%lld\n",n-2*((n+1)/2));
else printf("%lld\n",n);
}
else printf("%lld\n",n-2*f(1,0,1,n)+4*f(1,0,2,n));
}
return 0;
}

[P5172] Sum的更多相关文章

  1. LeetCode - Two Sum

    Two Sum 題目連結 官網題目說明: 解法: 從給定的一組值內找出第一組兩數相加剛好等於給定的目標值,暴力解很簡單(只會這樣= =),兩個迴圈,只要找到相加的值就跳出. /// <summa ...

  2. Leetcode 笔记 113 - Path Sum II

    题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...

  3. Leetcode 笔记 112 - Path Sum

    题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...

  4. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  5. BZOJ 3944 Sum

    题目链接:Sum 嗯--不要在意--我发这篇博客只是为了保存一下杜教筛的板子的-- 你说你不会杜教筛?有一篇博客写的很好,看完应该就会了-- 这道题就是杜教筛板子题,也没什么好讲的-- 下面贴代码(不 ...

  6. [LeetCode] Path Sum III 二叉树的路径和之三

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  7. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  8. [LeetCode] Split Array Largest Sum 分割数组的最大值

    Given an array which consists of non-negative integers and an integer m, you can split the array int ...

  9. [LeetCode] Sum of Left Leaves 左子叶之和

    Find the sum of all left leaves in a given binary tree. Example: 3 / \ 9 20 / \ 15 7 There are two l ...

随机推荐

  1. SpringBoot图片上传

    毕设终于写到头像上传了,本来想用Vue写来着,但是一直不顺利,还是对Vue用的不太熟.所以就用jquery写了. 首先添加以下标签 <img id="avatarPreview&quo ...

  2. 2017沈阳站 Tree

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6228 Tree Time Limit: 2000/1000 MS (Java/Others)    M ...

  3. 基于STM32L4的开源NBIOT开发资料

    基于STM32L4的开源NBIOT开发资料 1. 参考路径:http://www.stmcu.org/module/forum/forum.php?mod=viewthread&tid=615 ...

  4. PLSQL设置细节

    1. tnsnames.ora 文件设置中,前面不能包含空格,否则:无法解析连接字符串 2. 当一切配置都正确,但是还是无法连接:“身份证明检索失败” 解决:打开tns_admin配置连接串的目录,修 ...

  5. 申请的阿里云主机ubuntu系统无法显示中文

    系统ubuntu 16.04,中文的文件名也无法显示,因为中文包没安装,安装如下: sudo apt-get -y install language-pack-zh-hans sudo apt-get ...

  6. struts2参数传递总结

    需求1:登录页面填写表单,提交后进入action,action中能够获取填入的内容.[宏观分类:页面->action] 需求2:登录action从数据库校验完毕后,跳转至主页,主页显示当前登录的 ...

  7. prim算法和克鲁斯卡尔算法

    Prim 设图G=(V,E)是一个具有n个顶点的连通网,其生成树的顶点集合为U.首先把v0放入U,再在所有的u∈U,v∈V-U的边(u,v)∈E中找一条最小权值的边,加入生成树,并把该边的v加入U集合 ...

  8. 用JavaScript制作简单的计算器

    <html > <head> <title>简单计算器</title> <style type="text/css"> ...

  9. docker 配置 http 访问

    编辑docker宿主机文件/lib/systemd/system/docker.service sudo vi /lib/systemd/system/docker.service 修改以ExecSt ...

  10. 逆向基本使用:IDA

    如何导出IDA数据中数组的内容进行编程? 如这种: .data:00427A54 ; char byte_427A54[] .data:00427A54 byte_427A54 db 0FEh ; D ...