hdu 4746 Mophues (莫比乌斯反演 + 分块+线性筛)
来源:互联网 发布:三维设计软件 编辑:程序博客网 时间:2024/06/05 08:19
注意:
因为是多组询问(5000)而n又高达5e5,所以我们每次的时间一定要控制在logn或sqrt(n)内才能1s过,分块是必须的了。
然后是一个坑点:必须在线性筛里统计数量,自己写函数一个个统计会t在这上。
跟csu 1325的思路类似:需要预处理出
http://blog.csdn.net/wing_wuchen/article/details/76861929
249ms的代码:
#include<stdio.h>#include <iostream>#include<string.h>#include<math.h>#include<algorithm>#define eps 1e-8typedef long long int lli;using namespace std;const int maxn = 5e5+20;bool isprime[maxn];//int phi[maxn];int prime[maxn],miu[maxn];int cnt[maxn];void moblus(){ int num = 0;miu[1] = 1; for(lli i = 2;i < maxn;i++){ if(!isprime[i]){ prime[num++] = i,miu[i] = -1;//phi[i] = i-1; cnt[i] = 1; } for(lli j = 0;j < num && i*prime[j] < maxn;j++){ lli x = prime[j]; isprime[i*x] = 1;cnt[i*x] = cnt[i]+1; if(i%x){ miu[i*x] = -miu[i]; //phi[i*x] = phi[i] * phi[x]; } else{ miu[i*x] = 0; //phi[i*x] = phi[i] * x; break; } } }}int ff[maxn];bool v[maxn];int sum[25][maxn];int main(){ moblus(); for(int p = 0;p <= 19;p++){ for(int i = 1;i < maxn;i++){ if(cnt[i] > p || v[i]) continue; v[i] = true; for(int j = 1;j*i < maxn;j++){ ff[i*j] += miu[j]; } } for(int i = 1;i < maxn;i++){ sum[p][i] = sum[p][i-1]+ff[i]; } } int q,n,m,p; scanf("%d",&q); while(q--){ scanf("%d%d%d",&n,&m,&p); if(p > 19){ printf("%lld\n",(lli)m*(lli)n); continue; } if(n>m) swap(n,m); lli ans = 0,l; for(int i = 1;i <= n;i=l+1){ l = min(n/(n/i),m/(m/i)); ans += (lli)(sum[p][l]-sum[p][i-1])*(lli)(n/i)*(lli)(m/i); } printf("%lld\n",ans); } return 0;}
390ms的代码:
#include<stdio.h>#include <iostream>#include<string.h>#include<math.h>#include<algorithm>#define eps 1e-8typedef long long int lli;using namespace std;const int maxn = 5e5+20;bool isprime[maxn];//int phi[maxn];int prime[maxn],miu[maxn];int cnt[maxn];void moblus(){ int num = 0;miu[1] = 1; for(lli i = 2;i < maxn;i++){ if(!isprime[i]){ prime[num++] = i,miu[i] = -1;//phi[i] = i-1; cnt[i] = 1; } for(lli j = 0;j < num && i*prime[j] < maxn;j++){ lli x = prime[j]; isprime[i*x] = 1;cnt[i*x] = cnt[i]+1; if(i%x){ miu[i*x] = -miu[i]; //phi[i*x] = phi[i] * phi[x]; } else{ miu[i*x] = 0; //phi[i*x] = phi[i] * x; break; } } }}int sum[25][maxn];int main(){ moblus(); for(int i = 1;i < maxn;i++){ for(int j = 1;j*i < maxn;j++){ sum[cnt[i]][i*j] += miu[j];//我觉得可能是这里 内存的局部性原理导致100ms的延迟吧 } } for(int i = 1;i < maxn;i++){ sum[0][i] = sum[0][i-1]+sum[0][i]; } for(int p = 1;p <= 19;p++){ for(int i = 1;i < maxn;i++){ sum[p][i] = sum[p][i-1] + sum[p][i]; } for(int i = 1;i < maxn;i++){ sum[p][i] += sum[p-1][i]; } } int q,n,m,p; scanf("%d",&q); while(q--){ scanf("%d%d%d",&n,&m,&p); if(p > 19){ printf("%lld\n",(lli)m*(lli)n); continue; } if(n>m) swap(n,m); lli ans = 0,l; for(int i = 1;i <= n;i=l+1){ l = min(n/(n/i),m/(m/i)); ans += (lli)(sum[p][l]-sum[p][i-1])*(lli)(n/i)*(lli)(m/i); } printf("%lld\n",ans); } return 0;}
阅读全文
0 0
- hdu 4746 Mophues (莫比乌斯反演 + 分块+线性筛)
- HDU 4746 Mophues(莫比乌斯反演)
- HDU 4746 Mophues(莫比乌斯反演)
- HDU 4746-Mophues (莫比乌斯反演)
- hdu 4746 Mophues 莫比乌斯反演
- HDU 4746 Mophues (莫比乌斯反演应用)
- HDU 4746 Mophues【莫比乌斯反演】
- HDU 4746 Mophues (莫比乌斯反演应用)
- hdu 4746 Mophues 莫比乌斯 分块优化
- HDU4746 Mophues(莫比乌斯反演)
- HDU 4746 Mophues(有趣的前缀和/莫比乌斯反演)
- hdu4746 Mophues(莫比乌斯反演)-好题
- HDU 4746 Mophues 莫比乌斯第三弹
- NKOJ 4040 (CQOI 2017) 小Q的表格(莫比乌斯反演+分块+递推+线性筛/欧拉函数+分块+线性筛)
- 【bzoj2301】[HAOI2011]Problem b 莫比乌斯反演+线性筛法+数论分块
- 【bzoj2820】YY的GCD 线性筛法+莫比乌斯反演+数论分块
- 【bzoj3529】[Sdoi2014]数表 线性筛法+树状数组+莫比乌斯反演+数论分块
- 【bzoj3994】[SDOI2015]约数个数和 线性筛法+莫比乌斯反演+数论分块
- 快速打开文件命令行的三种方法
- 算法学习笔记--3.Binary Search & Algorithmic Complexity
- zlib window上编译
- idhttpserver用法
- codeforces825 D. Suitable Replacement 二分答案
- hdu 4746 Mophues (莫比乌斯反演 + 分块+线性筛)
- python读取caffemodel文件
- HDU
- HDU1015(dfs回溯)
- java.lang.IllegalArgumentException: width and height must be > 0
- 【USACO1.3.3】回文串
- STA接入AP的过程分析
- c++ const理解
- 【安卓学习之常见问题】 多国语言横竖屏时,自动切换到默认语言(android:configChanges的使用)