Sum

【问题描述】

给定一个正整数 N ( N <= 231 - 1 )

求:

【输入格式】

一共T+1行
第1行为数据组数T(T<=10)
第2~T+1行每行一个非负整数N,代表一组询问

【输出格式】

一共T行,每行两个用空格分隔的数ans1,ans2
【样例输入】

6
1
2
8
13
30
2333

【样例输出】

1 1
2 0
22 -2
58 -3
278 -3
1655470 2


题解:

首先推一波式子

上式就是杜教筛的原理

:

:

对于的求解方式在上面已经给出了

那么求出前项答案并记忆化状态,就能达到的时间复杂度

由于  ,那么我们求的每一项的参数都是  形式的

对于  小于等于的答案我们已经预处理出了

所以我们只需要记忆大于的答案

首先提出一个命题:对于  都不相同

证明:

假设 ,且

那么

mi , m表示两者的余数,它们的差为

因为,所以

那么,而,假设不成立

所以不存在,使得

证毕

所以在 时,成立

那么,我们就能直接使用数组存,对于每一个参数,我们将其除k的结果作为下标储存答案

 #include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxm = 2e6 + ;
const int maxn = 1e4 + ;
int n;
int pri[maxm];
bool vis[maxm];
struct couple
{
long long miu, phi;
};
couple ans[maxn], ori[maxm];
inline void Scan(int &x)
{
char c;
bool o = false;
while(!isdigit(c = getchar())) o = (c != '-') ? o : true;
x = c - '';
while(isdigit(c = getchar())) x = x * + c - '';
if(o) x = -x;
}
int m;
inline void Sieve()
{
int tot = ;
m = maxm - ;
ori[] = (couple) {, };
for(int i = ; i <= m; ++i)
{
if(!vis[i])
{
pri[++tot] = i;
ori[i] = (couple) {-, i - };
}
for(int j = ; j <= tot; ++j)
{
int k = pri[j];
long long s = (long long) i * k;
if(s > m) break;
vis[s] = true;
if(!(i % k))
{
ori[s].miu = ;
ori[s].phi = ori[i].phi * k;
break;
}
else
{
ori[s].miu = -ori[i].miu;
ori[s].phi = ori[i].phi * ori[k].phi;
}
}
}
for(int i = ; i <= m; ++i)
{
ori[i].miu += ori[i - ].miu;
ori[i].phi += ori[i - ].phi;
}
}
couple Solve(int x)
{
if(x <= m) return ori[x];
int e = n / x;
if(vis[e]) return ans[e];
int last;
couple c, s;
s.miu = , s.phi = x * ((long long) x + ) >> ;
for(long long i = ; i <= x; i = (long long) last + )
{
last = x / (x / i);
c = Solve(x / i);
s.miu -= c.miu * (long long) (last - i + ), s.phi -= c.phi * (long long) (last - i + );
}
vis[e] = true, ans[e] = s;
return s;
}
int main()
{
int T;
Scan(T);
Sieve();
while(T--)
{
Scan(n);
memset(vis, false, sizeof(vis));
if(n <= m) printf("%lld %lld\n", ori[n].phi, ori[n].miu);
else
{
couple answer = Solve(n);
printf("%lld %lld\n", answer.phi, answer.miu);
}
}

Sum BZOJ 3944的更多相关文章

  1. ●杜教筛入门(BZOJ 3944 Sum)

    入门杜教筛啦. http://blog.csdn.net/skywalkert/article/details/50500009(好文!) 可以在$O(N^{\frac{2}{3}})或O(N^{\f ...

  2. BZOJ 3944: Sum [杜教筛]

    3944: Sum 贴模板 总结见学习笔记(现在还没写23333) #include <iostream> #include <cstdio> #include <cst ...

  3. bzoj 3944: Sum(杜教筛)

    3944: Sum Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4930  Solved: 1313[Submit][Status][Discuss ...

  4. BZOJ 3944 Sum

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

  5. BZOJ.3944.Sum(Min_25筛)

    BZOJ 洛谷 不得不再次吐槽洛谷数据好水(连\(n=0,2^{31}-1\)都没有). \(Description\) 给定\(n\),分别求\[\sum_{i=1}^n\varphi(i),\qu ...

  6. bzoj 3944 Sum —— 杜教筛

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3944 杜教筛入门题! 看博客:https://www.cnblogs.com/zjp-sha ...

  7. BZOJ 3944 Sum 解题报告

    我们考虑令: \[F_n = \sum_{d|n}\varphi(d)\] 那么,有: \[\sum_{i=1}^{n}F_i = \sum_{i=1}^{n}\sum_{d|i}\varphi(d) ...

  8. 【刷题】BZOJ 3944 Sum

    Description Input 一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问 Output 一共T行,每行两个用空格分隔的数ans1,ans ...

  9. 「bzoj 3944: Sum」

    题目 杜教筛板子了 #include<iostream> #include<cstring> #include<cstdio> #include<cmath& ...

随机推荐

  1. 01_7_Struts_用Action的属性接收参数

    01_7_Struts_用Action的属性接收参数 1. 配置struts.xml文件 <package name="user" namespace="/user ...

  2. cocos2dx 加密spine文件遇到的问题(暂时没有解决方法)

    今天我研究了一下加密spine动画的加密的方法,图片肯定要加密的,所以我只选择加密图片,另外的一个altas文件和json文件就不做加密打算. 我的思路是通过TexturePacker打包成加密的文件 ...

  3. vue中文本域限制字数的方法

    用watch方法,来限制字数 <template> <div class="box"> <textarea v-model="title&q ...

  4. 【主席树】bzoj1112: [POI2008]砖块Klo

    数据结构划一下水 Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. ...

  5. Linux基础学习-网络管理

    Linux系统网络管理NetworkManager 1 启动网络管理服务和开机自启动 在rhel7中网路管理相关命令nmcli,nmtui,nmtui-edit,nm-connection-edito ...

  6. 15Shell脚本—流程控制

    流程控制语句 尽管可以通过使用Linux命令.管道符.重定向以及条件测试语句编写最基本的Shell脚本,但是这种脚本并不适用于生产环境.原因是它不能根据真实的工作需求来调整具体的执行命令,也不能根据某 ...

  7. UVa - 1592 Database(STL,优化)

    给一个n行m列的数据库表格,问有没有两个行 r1,r2 和 c1,c2,满足(r1,r2)的元素=(c1,c2)的元素. n≤10000,m≤10. 直接枚举4个肯定会T的.可以只枚举c1 c2,然后 ...

  8. strcpy和strncpy用法和区别

    1. strcpy函数:顾名思义字符串复制函数:原型:extern char *strcpy(char *dest,char *src); 功能:把从src地址开始且含有NULL结束符的字符串赋值到以 ...

  9. python基础学习笔记——循环语句(while、for)

    while 循环 流程控制语句 while 1.基本循环 while 条件: # 循环体 # 如果条件为真,那么循环则执行 # 如果条件为假,那么循环不执行   2.break break 用于退出当 ...

  10. JAVA-基础(二) java.lang

    1.String类提供了许多从String对象中截取字符的方法 1.1 char charAt(int where) 1.2 void getChars(int sourceStart, int so ...