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的xml配置里,最好不要配置xsd的版本名称
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 随机森林(Random Forest)
阅读目录 1 什么是随机森林? 2 随机森林的特点 3 随机森林的相关基础知识 4 随机森林的生成 5 袋外错误率(oob error) 6 随机森林工作原理解释的一个简单例子 7 随机森林的Pyth ...
- 用junit对java代码进行测试,需要注意
1.用@Test注解的方法必须没有返回值,返回值类型无:void 2.用@Test注解的方法必须没有参数.
- Yii2总结
1. Web访问流程(即在浏览器中输入一个网址至浏览器展现页面结果的过程) a. 将输入的网址提取出域名,在本地hosts文件中查找对应的IP地址(windows为C:/windows/system3 ...
- How to split DMG on macOS
hdiutil segment /users/test/test1.dmg -segmentsize 4000m -o /users/test/test2.dmg
- Razor Pages with ASP.NET Core 2
With ASP.NET Core 2 we get another way of building web applications. It’s one of those new things th ...
- 页面传递的都是string ; 每个标签要有name的原因是为了取值 因为传递给后台是键值对的形式
页面传递的都是string ; 每个标签要有name的原因是为了取值 因为传递给后台是键值对的形式
- Sublime Text3 如何开启Debug
打开setting-user 首选项——>Package Settings——>Package Control——>settings-user 添加"debug" ...
- java json转换(一)
主要使用了2个类 JsonConvert.class 和 ConvertHelper.class 由于常规转json.只要model牵涉到复杂的关联实体对象.那么就会出现 深度循环的错误. 因此这里通 ...
- POJ 3667 Hotel(算竞进阶习题)
线段树区间染色 题目要求最大的连续段的左端点,我们在查询的时候返回最左端即可,注意查找顺序,应该从左到右!! 另外这类染色的push_down其实比较简单,直接染成上一层的标记即可 push_up和连 ...