【51Nod 1239】欧拉函数之和
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1239
还是模板题。
杜教筛:$$S(n)=\frac{n(n+1)}{2}-\sum_{i=2}^nS\left(\left\lfloor\frac ni\right\rfloor\right)$$
基于质因子分解的筛法:详见2016年论文《积性函数求和的几种方法》(讲得很详细的~~~)
为什么我写的洲哥筛常熟巨大QAQ
杜教筛\(O\left(n^{\frac 23}\right)\)
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll N = 1E10;
const int UP = 3981071;
const int mo = 1000000007;
const int ni2 = 500000004;
int phi[UP + 3], prime[UP + 3], num = 0, sum[UP + 3];
bool notp[UP + 3];
void Euler_shai() {
sum[1] = phi[1] = 1;
for (int i = 2; i <= UP; ++i) {
if (!notp[i]) {
prime[++num] = i;
phi[i] = i - 1;
}
for (int j = 1, pro; j <= num && (pro = prime[j] * i) <= UP; ++j) {
notp[pro] = true;
if (i % prime[j] == 0) {
phi[pro] = phi[i] * prime[j];
break;
} else
phi[pro] = phi[i] * phi[prime[j]];
}
sum[i] = (sum[i - 1] + phi[i]) % mo;
}
}
struct HashTable {
static const int p = 1000007;
ll val[p], ref[p];
HashTable() {memset(ref, -1, sizeof(ref));}
void add(ll pos, ll nu) {
int tmp = pos % p;
while (ref[tmp] != -1) {
if (ref[tmp] == pos) return;
++tmp; if (tmp == p) tmp = 0;
}
ref[tmp] = pos;
val[tmp] = nu;
}
ll query(ll pos) {
int tmp = pos % p;
while (ref[tmp] != pos) {++tmp; if (tmp == p) tmp = 0;}
return val[tmp];
}
} HT;
ll Sum(ll x) {
return x <= UP ? sum[x] : HT.query(x);
}
void DJ_shai(ll n) {
for (ll i = n, y; i >= 1; i = n / (y + 1)) {
y = n / i;
if (y <= UP) continue;
ll ret = 0;
for (ll j = 2, l, pre = 1; j <= y; ++j) {
l = y / j;
j = y / l;
ret = (ret + Sum(l) * ((j - pre) % mo) % mo) % mo;
pre = j;
}
HT.add(y, (y % mo * ((y + 1) % mo) % mo * ni2 % mo - ret + mo) % mo);
}
}
main() {
Euler_shai();
ll top;
scanf("%lld", &top);
DJ_shai(top);
printf("%lld\n", Sum(top));
return 0;
}
基于质因子分解的筛法\(O\left(\frac{n^{\frac 34}}{\log n}\right)\)
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1E10;
const int UP = 1E5;
const int mo = 1000000007;
const int ni2 = 500000004;
bool notp[UP + 3];
ll G0[UP * 2 + 3], G1[UP * 2 + 3], F[UP * 2 + 3], J[UP * 2 + 3];
int prime[UP + 3], sum_prime[UP + 3], sum_phi[UP + 3], phi[UP + 3], sum_p[UP + 3];
int pre[UP * 2 + 3], num = 0, ma[UP + 3];
void Euler_shai(int n) {
phi[1] = sum_phi[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!notp[i]) {
prime[++num] = i;
sum_prime[num] = (sum_prime[num - 1] + i) % mo;
phi[i] = i - 1;
sum_p[i] = (sum_p[i - 1] + i - 1) % mo;
ma[i] = num;
} else {
sum_p[i] = sum_p[i - 1];
ma[i] = ma[i - 1];
}
for (int j = 1, pro; j <= num && (pro = i * prime[j]) <= n; ++j) {
notp[pro] = true;
if (i % prime[j] == 0) {
phi[pro] = 1ll * phi[i] * prime[j] % mo;
break;
} else
phi[pro] = 1ll * phi[i] * phi[prime[j]] % mo;
}
sum_phi[i] = (sum_phi[i - 1] + phi[i]) % mo;
}
}
struct HashTable {
static const int ppp = 2333333;
ll ref[ppp]; int val[ppp];
void clr() {memset(ref, -1, sizeof(ref)); ref[0] = val[0] = 0;}
void add(ll pos, int nu) {
int tmp = pos % ppp;
while (ref[tmp] != -1) {++tmp; if (tmp == ppp) tmp = 0;}
ref[tmp] = pos; val[tmp] = nu;
}
int query(ll pos) {
int tmp = pos % ppp;
while (ref[tmp] != pos) {++tmp; if (tmp == ppp) tmp = 0;}
return val[tmp];
}
} HT;
#define maa(x) (x >= sqc ? num : ma[x])
ll ZY_shai(ll n) {
int cnt = 0, sqf = floor(sqrt(n)), sqc = ceil(sqrt(n));
HT.clr();
for (ll i = n, y; i >= 1; i = n / (y + 1)) {
J[++cnt] = (y = n / i);
HT.add(y, cnt);
G0[cnt] = y;
G1[cnt] = y % mo * ((y + 1) % mo) % mo * ni2 % mo;
pre[cnt] = 0;
}
ll pp, delta;
for (int i = 1, p = prime[i]; i <= num; p = prime[++i]) {
pp = 1ll * p * p;
for (int j = cnt; j >= 1 && J[j] >= pp; --j) {
int id = HT.query(J[j] / p);
delta = max(G0[id] - (i - 1 - pre[id]), 1ll);
G0[j] -= delta;
delta = (G1[id] - ((sum_prime[min(i - 1, maa(J[id]))] - sum_prime[pre[id]] + mo) % mo) + mo) % mo;
G1[j] = (G1[j] - p * delta % mo + mo) % mo;
pre[j] = i;
}
}
for (int j = cnt; j >= 1; --j) {
G0[j] = max(G0[j] - (num - pre[j]), 1ll);
G1[j] = (G1[j] - ((sum_prime[maa(J[j])] - sum_prime[pre[j]] + mo) % mo) + mo) % mo;
}
ll ans = 0;
for (int i = 1; i < sqc; ++i) {
int id = HT.query(n / i);
ans = (ans + (1ll + G1[id] - G0[id] + mo) % mo * phi[i] % mo) % mo;
}
ll prep = 0, sqrprep;
for (int j = 1; j <= cnt; ++j) F[j] = 1;
for (int i = num, p = prime[i]; i >= 1; p = prime[--i]) {
pp = 1ll * p * p;
for (int j = cnt; j >= 1 && J[j] >= pp; --j) {
ll J_j = J[j];
if (J_j < sqrprep) {
if (J_j >= prep) F[j] = (1 + sum_p[min(J_j, 1ll * sqf)] - sum_p[prep - 1] + mo) % mo;
else F[j] = 1;
}
int id = HT.query(J_j / p);
if (J[id] < sqrprep) {
if (J[id] >= prep) delta = (1 + sum_p[min(J[id], 1ll * sqf)] - sum_p[prep - 1] + mo) % mo;
else delta = 1;
} else
delta = F[id];
F[j] = (F[j] + (p - 1) * delta % mo) % mo;
ll pic = pp;
while (J_j >= pic) {
id = HT.query(J_j / pic);
if (J[id] < sqrprep) {
if (J[id] >= prep) delta = (1 + sum_p[min(J[id], 1ll * sqf)] - sum_p[prep - 1] + mo) % mo;
else delta = 1;
} else
delta = F[id];
F[j] = (F[j] + pic / p * (p - 1) % mo * delta % mo) % mo;
pic *= p;
}
}
prep = p; sqrprep = pp;
}
return ((ans + F[cnt]) % mo - sum_phi[sqc - 1] + mo) % mo;
}
int main() {
ll top;
scanf("%lld\n", &top);
Euler_shai((int) sqrt(top));
printf("%lld\n", ZY_shai(top));
return 0;
}
【51Nod 1239】欧拉函数之和的更多相关文章
- [51Nod 1244] - 莫比乌斯函数之和 & [51Nod 1239] - 欧拉函数之和 (杜教筛板题)
[51Nod 1244] - 莫比乌斯函数之和 求∑i=1Nμ(i)\sum_{i=1}^Nμ(i)∑i=1Nμ(i) 开推 ∑d∣nμ(d)=[n==1]\sum_{d|n}\mu(d)=[n== ...
- 51nod 1239 欧拉函数之和(杜教筛)
[题目链接] https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1239 [题目大意] 计算欧拉函数的前缀和 [题解] 我们 ...
- 51nod 1239 欧拉函数之和【欧拉函数+杜教筛】
和bzoj 3944比较像,但是时间卡的更死 设\( f(n)=\sum_{d|n}\phi(d) g(n)=\sum_{i=1}^{n}f(i) s(n)=\sum_{i=1}^{n}\phi(i) ...
- 51 NOD 1239 欧拉函数之和(杜教筛)
1239 欧拉函数之和 基准时间限制:3 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 收藏 关注 对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目.此函数以其首名研究 ...
- 【51nod】1239 欧拉函数之和 杜教筛
[题意]给定n,求Σφ(i),n<=10^10. [算法]杜教筛 [题解] 定义$s(n)=\sum_{i=1}^{n}\varphi(i)$ 杜教筛$\sum_{i=1}^{n}(\varph ...
- 【51nod】1239 欧拉函数之和
题解 写完上一道就开始写这个,大体上就是代码改了改而已= = 好吧,再推一下式子! \(\sum_{i = 1}^{n}i = \sum_{i = 1}^{n}\sum_{d | i}\phi(d) ...
- 51Nod 1239 欧拉函数前n项和 杜教筛
http://www.51nod.com/Challenge/Problem.html#!#problemId=1239 AC代码 #include <bits/stdc++.h> #de ...
- 51nod1239 欧拉函数之和
跟1244差不多. //由于(x+1)没有先mod一下一直WA三个点我... //由于(x+1)没有先mod一下一直WA三个点我... #include<cstdio> #include& ...
- 欧拉函数之和(51nod 1239)
对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命名,它又称为Euler's totient function.φ函数.欧拉商数等.例如:φ(8) = 4(Phi( ...
- 【51nod-1239&1244】欧拉函数之和&莫比乌斯函数之和 杜教筛
题目链接: 1239:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1239 1244:http://www.51nod. ...
随机推荐
- springboot:Spring boot中mongodb的使用(山东数漫江湖)
mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置 ...
- Windows Server 2008 R2英文版修改桌面主题(Win7主题)
1:首先打开Server Manager(凡是不知道在那里开发均可像Win7一样在运行里面搜索) 2:然后在左边的树形菜单中选择:Feature 点击右边页面中的:Add Features 这时候会出 ...
- HTML跳转新窗口的方法
笔试遇到这样的一个问题,特意整理一下. 方法一 纯HTML <a href="http://www.cnblogs.com" target="_blank" ...
- Coursera在线学习---第十节.大规模机器学习(Large Scale Machine Learning)
一.如何学习大规模数据集? 在训练样本集很大的情况下,我们可以先取一小部分样本学习模型,比如m=1000,然后画出对应的学习曲线.如果根据学习曲线发现模型属于高偏差,则应在现有样本上继续调整模型,具体 ...
- LCD实验学习笔记(五):MMU
内存管理分别页表机制和内存分配机制两块. 页表机制就是管理设备真实物理地址与虚拟地址的动态或静态的映射,基于cpu内部的mmu(内存管理单元)进行. CP15(协处理器)的C0(缓存)是一级页表,含4 ...
- Linux 入门记录:十五、Linux 网络基本配置
一.以太网(Ethernet) 以太网(Ethernet)是一种计算机局域网技术.IEEE 组织的 IEEE 802.3 标准制定了以太网的技术标准,它规定了包括物理层的连线.电子信号和介质访问层协议 ...
- JSP(3) - 9个JSP内置对象 - 小易Java笔记
1.9个JSP内置对象 内置对象引用名称 对应的类型 request HttpServletRequest response HttpServletResponse config Servle ...
- [会装]Spark standalone 模式的安装
1. 简介 以standalone模式安装spark集群bin运行demo. 2.环境和介质准备 2.1 下载spark介质,根据现有hadoop的版本选择下载,我目前的环境中的hadoop版本是2. ...
- [ python ] hasattr()、getattr()、setattr() 三者关系及运用
hasattr(object, name) 判断一个对象(object)是否存在name属性或方法,返回boolean值,有name属性返回True, 否则返回False In [1]: class ...
- MySQL乐观锁
MySQL悲观锁是依靠数据库的锁机制来实现,以实现最大程度上的独占性.但由于现代的web系统一般都是高并发的,所以悲观锁在这样的情况下的适用性不高,所以我们有了和悲观锁相对应的乐观锁. 乐观锁,是说假 ...