BUPT2017 wintertraining(15) #5H

HDU- 4947

题意

有一个长度为l的数组,现在有m个操作,第1种为1 n d v,给下标x 满足gcd(x,n)=d的\(a_x\)增加v。第2种为2 x,查询\(\sum_{i=1}^x a_i\)。

数据范围:\(1\le n,d,v\le2\cdot 10^5,1\le x\le l\)

题解

设\(f_i\)满足\(a_i=\sum_{d|i} f_d\),用树状数组存储\(f_i\)的前缀和。

\[a_x+=v\cdot[gcd(x,n)=d]=v\cdot[gcd(x/d,n/d)=1]
\]

根据莫比乌斯函数(关于莫比乌斯反演可以看这篇论文:贾志鹏线性筛法与积性函数)的性质,我们知道\(\sum_{d|n}\mu(d)=[n=1]\),(这个d和上面的d不是同一个,下面换为p表示) 因此

\[a_x+=v\cdot\sum_{p|gcd(x/d,n/d)}\mu(p)=v\cdot \sum_{p|\frac x d,p|\frac n d}\mu(p)
\]

于是对于给定的n和d,\(\frac n d\)的因子p的d倍就是符合条件的下标x的一个因子。

莫比乌斯反演可得:

\(f(n)=\sum_{d|n}\mu(\frac n d)a(n)\)

因此\(f_{pd}=\sum \mu(p)a(pd)\),于是对于1操作,我们只要给\(f_{pd}\)加上\(v\cdot \mu (p)\)即可。

2操作,是对\(a_i\)求和:

\[\sum_{i=1}^x a_i=\sum_{i=1}^x \sum_{d|x}f_d
\]

对于固定的d来说,1~x内\(f_d\)要加\(\lfloor \frac x d\rfloor\)次。再分块加速一下,也就是对于\(\lfloor\frac x d\rfloor\)相同的d,把\(f_d\)区间和求出来再乘上\(\lfloor\frac x d\rfloor\),设这个区间是[d1,d2],那么d2=x/(x/d1) (整除),为什么呢?因为d2是满足\(\frac x d \ge \lfloor \frac x {d1}\rfloor=k\)的最大的整数d,那么\(x\ge d2\cdot k\),所以\(\frac x k \ge d2\),也就是d2=\(\lfloor\frac x k\rfloor\)。

这题的时间复杂度:

预处理出1~N的所有因子,\(O(n\sqrt n)\)。

计算莫比乌斯函数,\(O(n)\)。

1操作,因子有\(\sqrt n\)个,增加是\(O(\log n)\),总的是\(O(m\sqrt n \log n)\)。

2操作,查询\(O(log n)\),分块\(O(\sqrt n)\),也是\(O(m\sqrt n \log n)\)。

总的就是\(O(m\sqrt n \log n)\)

官方题解:

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<vector>
  4. #define ll long long
  5. #define N 200005
  6. using namespace std;
  7. int miu[N],prime[N],cnt;
  8. ll sum[N],last,lasttemp,temp;
  9. vector<int>fac[N];
  10. bool check[N];
  11. ll ans;
  12. ll getsum(int x){
  13. ll ans=0;
  14. for(;x;x-=x&-x)ans+=sum[x];
  15. return ans;
  16. }
  17. void add(int x,int v){
  18. for(;x<N;x+=x&-x)sum[x]+=v;
  19. }
  20. void Mobius(){
  21. miu[1]=1;
  22. for(int i=2;i<N;i++){
  23. if(!check[i]){
  24. prime[cnt++]=i;
  25. miu[i]=-1;
  26. }
  27. for(int j=0;j<cnt;j++){
  28. if(i*prime[j]>N)break;
  29. check[i*prime[j]]=1;
  30. if(i%prime[j])miu[i*prime[j]]=-miu[i];
  31. else break;
  32. }
  33. }
  34. }
  35. int main(){
  36. int l,m,cas=0;
  37. Mobius();
  38. for(int i=1;i<N;i++)
  39. for(int j=i;j<N;j+=i)
  40. fac[j].push_back(i);
  41. while(scanf("%d%d",&l,&m),l,m){
  42. printf("Case #%d:\n",++cas);
  43. memset(sum,0,sizeof sum);
  44. while(m--){
  45. int n,d,v,x;
  46. scanf("%d",&n);
  47. if(n==1){
  48. scanf("%d%d%d",&n,&d,&v);
  49. if(n%d)continue;
  50. n/=d;
  51. for(int i=0;i<fac[n].size();i++){
  52. x=fac[n][i];
  53. add(x*d,miu[x]*v);
  54. }
  55. }else{
  56. scanf("%d",&n);
  57. ans=temp=0;
  58. for(int i=1;i<=n;i=last+1){
  59. last=n/(n/i);
  60. lasttemp=temp;
  61. temp=getsum(last);
  62. ans+=n/i*(temp-lasttemp);
  63. }
  64. printf("%lld\n",ans);
  65. }
  66. }
  67. }
  68. }

相似题,待做: SPOJ PGCD - Primes in GCD Table (好题! 莫比乌斯反演+分块求和优化)

待看的文章:读贾志鹏线性筛有感 (莫比乌斯函数的应用)

【HDU4947】GCD Array (莫比乌斯反演+树状数组)的更多相关文章

  1. 【HDU4947】GCD Array(莫比乌斯反演+树状数组)

    点此看题面 大致题意: 一个长度为\(n\)的数组,实现两种操作:将满足\(gcd(i,k)=d\)的\(a_i\)加上\(v\),询问\(\sum_{i=1}^xa_i\). 对于修改操作的推式子 ...

  2. HDU4947GCD Array(莫比乌斯反演+树状数组)

    题面 传送门 题解 orz ljz 相当于每一个数要加上 \[v\times [\gcd(i,n)=d]=v\times [\gcd(i/d,n/d)=1]=v\times \sum_{p|{i\ov ...

  3. BZOJ 3259 [Sdoi2014]数表 (莫比乌斯反演 + 树状数组)

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2321  Solved: 1187[Submit][Status ...

  4. 【BZOJ3529】[Sdoi2014]数表 莫比乌斯反演+树状数组

    [BZOJ3529][Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和 ...

  5. BZOJ 3529 [Sdoi2014]数表 (莫比乌斯反演+树状数组+离线)

    题目大意:有一张$n*m$的数表,第$i$行第$j$列的数是同时能整除$i,j$的所有数之和,求数表内所有不大于A的数之和 先是看错题了...接着看对题了发现不会做了...刚了大半个下午无果 看了Po ...

  6. BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1399  Solved: 694[Submit][Status] ...

  7. 洛谷P3312 [SDOI2014]数表(莫比乌斯反演+树状数组)

    传送门 不考虑$a$的影响 设$f(i)$为$i$的约数和 $$ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^nf(gcd(i,j))$$ $$=\sum\limi ...

  8. BZOJ 3529 [Sdoi2014]数表 ——莫比乌斯反演 树状数组

    $ans=\sum_{i=1}^n\sum_{j=1}^n\sigma(gcd(i,j))$ 枚举gcd为d的所有数得到 $ans=\sum_{d<=n}\sigma(d)*g(d)$ $g(d ...

  9. 【BZOJ3529】【莫比乌斯反演 + 树状数组】[Sdoi2014]数表

    Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为 能同时整除i和j的所有自然数之和.给定a,计算数表中不大于 ...

随机推荐

  1. codeforces#1090 D. New Year and the Permutation Concatenation(打表找规律)

    题意:给出一个n,生成n的所有全排列,将他们按顺序前后拼接在一起组成一个新的序列,问有多少个长度为n的连续的子序列和为(n+1)*n/2 题解:由于只有一个输入,第一感觉就是打表找规律,虽然表打出来了 ...

  2. dynamo与cassandra区别

    虽说cassandra是dynamo的开源版本,但两者还是有很大区别的. coordinator的选取: 在dynamo论文中,一般是preference list中N个副本的第一个 为什么叫“一般” ...

  3. 软工网络15团队作业4——Alpha阶段敏捷冲刺

    Deadline: 2018-4-29 10:00PM,以提交至班级博客时间为准. 根据以下要求,团队在日期区间[4.16,4.29]内,任选8天进行冲刺,冲刺当天晚10点前发布一篇随笔,共八篇. 另 ...

  4. 多线程系列之八:Thread-Per-Message模式

    一,Thread-Per-Message模式 翻译过来就是 每个消息一个线程.message可以理解为命令,请求.为每一个请求新分配一个线程,由这个线程来执行处理.Thread-Per-Message ...

  5. CGI、FAST-CGI、PHP-CGI、PHP-FPM的关系

    转自:https://www.awaimai.com/371.html 关于这一类的文章还有:https://zhuanlan.zhihu.com/p/20694204 在搭建 LAMP/LNMP 服 ...

  6. vim 永久添加行号

    sudo vi /etc/vim/vimrc 打开vimrc文件,最下面添加set nu,保存就可以添加行号了,set autoindent是自动换行

  7. 获取环境变量,0x000000cb 操作系统找不到已输入的环境选项

    include "stdafx.h" #include <Windows.h> #include <iostream> #pragma warning(di ...

  8. jmeter5.0生成html报告 快速入门

    JMeter性能测试5.0时代之-多维度的图形化HTML报告 快速入门 1.确认基本配置 在jmeter.properties或者user.properties确认如下配置项: jmeter.save ...

  9. C/S和B/S应用程序的区别

    一.C/S和B/S介绍: 1.C/S介绍: Client/Server架构,即客户端/服务器架构.是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销 ...

  10. 思维导图,UML图,程序流程图制作从入门到精通

    工具: https://www.processon.com/ 第一 用例图 第二 时序图 第三 流程图