BZOJ3512 DZY Loves Math IV

解:这又是什么神仙毒瘤题......
我直接把后面那个phi用phi * I = id反演一波,得到个式子,然后推不动了......
实际上第一步我就大错特错了。考虑到n很小,我们有

然后计算S,我们根据欧拉函数的性质有:

于是只考虑n sqr free的情况。
到这里有两种解法,一种是暴力递归。

考虑n的一个因子p,我们先提取出前面那一项,但是这还不够。因为当p|i的时候应该提出来p = phi[p] + 1。
于是我们在后面补上。令i = pt,就有了递归式。
#include <cstdio>
#include <map> typedef long long LL;
const int N = , T = ;
const LL MO = 1e9 + , INF = 0x7f7f7f7f7f7f7f7fll; int phi[N], p[N], top, last[N];
LL Phi[N], inv2;
bool vis[N]; namespace Hash {
struct Node {
LL val, ans;
int nex;
Node(LL x = , LL y = , int z = ) {
val = x;
ans = y;
nex = z;
}
}node[]; int top;
const int mod = ;
int e[mod];
inline void insert(LL p, LL v) {
int x = p % mod;
node[++top] = Node(p, v, e[x]);
e[x] = top;
return;
}
inline LL find(LL p) {
int x = p % mod;
for(int i = e[x]; i; i = node[i].nex) {
if(node[i].val == p) return node[i].ans;
}
return -INF;
}
} inline void getp(int n) {
phi[] = ;
for(int i = ; i <= n; i++) {
if(!vis[i]) {
p[++top] = i;
phi[i] = i - ;
last[i] = i;
}
for(int j = ; j <= top && i * p[j] <= n; j++) {
vis[i * p[j]] = ;
last[i * p[j]] = p[j];
if(i % p[j] == ) {
phi[i * p[j]] = phi[i] * p[j];
break;
}
phi[i * p[j]] = phi[i] * (p[j] - );
}
}
for(int i = ; i <= n; i++) {
Phi[i] = (Phi[i - ] + phi[i]) % MO;
}
return;
} LL getPhi(LL x) {
if(x <= ) return ;
if(x <= T) return Phi[x];
LL temp = Hash::find(x);
if(temp != -INF) return temp;
//printf("getPhi %lld T = %d\n", x, T);
LL ans = (x % MO) * ((x + ) % MO) % MO * inv2 % MO;
for(LL i = , j; i <= x; i = j + ) {
j = x / (x / i);
ans -= ((j - i + ) % MO) * getPhi(x / i) % MO;
ans = (ans % MO + MO) % MO;
}
Hash::insert(x, ans);
return ans;
} LL S(LL n, LL m) {
//printf("S : %lld %lld \n", n, m);
if(n == ) return getPhi(m);
if(m == ) return ;
if(m == ) return phi[n];
LL p = last[n];
LL ans = (phi[p] * S(n / p, m) % MO + S(n, m / p)) % MO;
return ans;
} int main() {
inv2 = (MO + ) / ;
getp(T);
LL nn, m;
scanf("%lld%lld", &nn, &m);
LL ans = ;
for(int i = ; i <= nn; i++) {
LL p = , q = , n = i;
while(n > ) {
LL temp = last[n];
p *= temp;
n /= temp;
while(n % temp == ) {
n /= temp;
q *= temp;
}
}
ans = (ans + q * S(p, m) % MO) % MO;
}
printf("%lld\n", ans);
return ;
}
TLE
还有一种继续推:

其中d = gcd(i,n)
有个关键点是n是sqr free...否则一直想不明白。
接下来把这个式子带入S的定义式中。

这样就可以递归了。
注意......这个S也可以记忆化的,否则死活过不去。用map。
#include <cstdio>
#include <map> typedef long long LL;
const int N = , T = ;
const LL MO = 1e9 + , INF = 0x7f7f7f7f7f7f7f7fll; int p[N], last[N], top, phi[N];
LL Phi[N], inv2;
bool vis[N]; std::map<LL, LL> mp[], Hash; inline void getp(int n) {
phi[] = ;
for(int i = ; i <= n; i++) {
if(!vis[i]) {
p[++top] = i;
phi[i] = i - ;
last[i] = i;
}
for(int j = ; j <= top && i * p[j] <= n; j++) {
vis[i * p[j]] = ;
last[i * p[j]] = p[j];
if(i % p[j] == ) {
phi[i * p[j]] = phi[i] * p[j];
break;
}
phi[i * p[j]] = phi[i] * (p[j] - );
}
}
for(int i = ; i <= n; i++) {
Phi[i] = (Phi[i - ] + phi[i]) % MO;
}
return;
} LL getPhi(LL x) {
if(x <= ) return ;
if(x <= T) return Phi[x];
if(Hash.count(x)) return Hash[x];
//printf("Phi %lld \n", x);
LL ans = (x % MO) * ((x + ) % MO) % MO * inv2 % MO;
for(LL i = , j; i <= x; i = j + ) {
j = x / (x / i);
ans -= ((j - i + ) % MO) * getPhi(x / i) % MO;
ans = (ans % MO + MO) % MO;
}
return Hash[x] = ans;
} LL S(int n, LL m) {
//printf("S %d %lld \n", n, m);
if(n == ) return getPhi(m);
if(m == ) return phi[n];
if(m == ) return ;
if(mp[n][m]) return mp[n][m];
LL ans = ;
for(int i = ; i * i <= n; i++) {
if(n % i) continue;
ans += phi[n / i] * S(i, m / i) % MO;
if(i * i < n) {
ans += phi[i] * S(n / i, m / (n / i)) % MO;
}
ans = (ans % MO + MO) % MO;
}
return mp[n][m] = ans;
} int main() {
inv2 = (MO + ) / ;
int nn; LL m;
getp(T);
scanf("%d%lld", &nn, &m);
LL ans = ;
for(int i = ; i <= nn; i++) {
int n = i, p = , q = ;
//printf("i = %d \n", i);
while(n > ) {
int temp = last[n];
n /= temp;
p *= temp;
while(n % temp == ) {
n /= temp;
q *= temp;
}
}
ans += q * S(p, m) % MO;
ans = (ans % MO + MO) % MO;
}
printf("%lld\n", ans);
return ;
}
AC代码
这个时间到底是怎么算的啊......玄学。
BZOJ3512 DZY Loves Math IV的更多相关文章
- BZOJ3512 DZY Loves Math IV(杜教筛+线性筛)
注意到n很小,考虑枚举i.现在要求的是f(n,m)=Σφ(in) (i=1~m).显然当n没有平方因子时,φ(in)=φ(i)·φ(n/gcd(i,n))·gcd(i,n).利用φ*1=id又可得φ( ...
- 【BZOJ3512】DZY Loves Math IV(杜教筛)
[BZOJ3512]DZY Loves Math IV(杜教筛) 题面 BZOJ 求 \[\sum_{i=1}^n\sum_{j=1}^m\varphi(ij)\] 其中\(n\le 10^5,m\l ...
- BZOJ 3512: DZY Loves Math IV [杜教筛]
3512: DZY Loves Math IV 题意:求\(\sum_{i=1}^n \sum_{j=1}^m \varphi(ij)\),\(n \le 10^5, m \le 10^9\) n较小 ...
- BZOJ3512:DZY Loves Math IV
传送门 Sol 好神仙的题目.. 一开始就直接莫比乌斯反演然后就 \(GG\) 了 orz 题解 permui 枚举 \(n\),就是求 \(\sum_{i=1}^{n}S(i,m)\) 其中\(S( ...
- 【bzoj3512】DZY Loves Math IV 杜教筛+记忆化搜索+欧拉函数
Description 给定n,m,求\(\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi(ij)\)模10^9+7的值. Input 仅一行,两个整数n,m. Output 仅 ...
- ●BZOJ 3512 DZY Loves Math IV
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3512 题解: $$求ANS=\sum_{i=1}^{N}\sum_{j=1}^{M}\phi ...
- 【刷题】BZOJ 3512 DZY Loves Math IV
Description 给定n,m,求 模10^9+7的值. Input 仅一行,两个整数n,m. Output 仅一行答案. Sample Input 100000 1000000000 Sampl ...
- bzoj 3512: DZY Loves Math IV
Description 给定n,m,求 模10^9+7的值. Solution 设 \(S(n,m)\) 表示 \(\sum_{i=1}^{m}\phi(n*i)\) \(Ans=\sum_{i=1} ...
- bzoj 3512: DZY Loves Math IV【欧拉函数+莫比乌斯函数+杜教筛】
参考:http://blog.csdn.net/wzf_2000/article/details/54630931 有这样一个显然的结论:当\( |\mu(n)|==1 \)时,\( \phi(nk) ...
随机推荐
- spring初始化bean时执行某些方法完成特定的初始化操作
在项目中经常会在容器启动时,完成特定的初始化操作,如资源文件的加载等. 一 实现的方式有三种: 1.使用@PostConstruct注解,该注解作用于void方法上 2.在配置文件中配置init-me ...
- VSC软件快捷键
Shift + Alt + F 格式化 Ctrl+Shift+P, F1显示命令面板 Ctrl+P快速打开,进入File… Ctrl + Shift + N新窗口/实例 Ctrl + Shift + ...
- Linux基础学习笔记5-软件管理
包管理器 二进制应用程序的组成部分: 二进制文件.库文件.配置文件.帮助文件 程序包管理器: debian:deb文件.dpkg包管理器 redhat:rpm文件.rpm包管理器 rpm:Redhat ...
- hive自定义函数
- k8s容器的资源限制
1.k8s支持内存和cpu的限制 requests:容器运行需求,最低保障limits:限制,硬限制(资源上限) CPU: 1颗逻辑CPU(1核CPU=4个逻辑CPU) 1物理核=1000个微核(mi ...
- Python:matplotlib绘制散点图
与线型图类似的是,散点图也是一个个点集构成的.但不同之处在于,散点图的各点之间不会按照前后关系以线条连接起来. 用plt.plot画散点图 奇怪,代码和前面的例子差不多,为什么这里显示的却是散 ...
- python3高级编程
1. SMTP发送邮件 internet相关协议: http:网页访问相关,httplib,urllib,xmlrpclib ftp:文件传输相关, ftplib, urllib nntp:新闻和帖子 ...
- nginx 负载均衡(默认算法)
使用 nginx 的upstream模块只需要几步就可以实现一个负载均衡: 在 nginx 配置文件中添加两个server server { listen ; server_name 192.168. ...
- time模块 转换关系图
import time t = time.time() #获取目前时间 t_struck = time.localtime(t) #time.gmtime() utc时区 t_str = time.s ...
- JavaScript Decorators 的简单理解
Decorators,装饰器的意思, 所谓装饰就是对一个物件进行美化,让它变得更漂亮.最直观的例子就是房屋装修.你买了一套房子,但是毛坯房,你肯定不想住,那就对它装饰一下,床,桌子,电视,冰箱等一通买 ...