题目大意:给一个n个整数的数列,q次询问,每次询问区间[l,r]中与区间中其它数互质的数的个数.。

题目分析:离线处理,这里以询问区间的左端点从小到大的顺序为例。为了叙述方便,用f(l,r)表示区间[l,r]中与区间中其它数互质的数的个数.。每次用线段树或树状数组维护以 a(i)(1<=i<=n) 为左端点的所有区间的 f 值的前缀和。左端点从1~n,每变化一次,便做一次更新操作。这样,f(l,r)=sum(l)-sum(r+1)。对于数列中的每个元素a(i),预处理出其左边第一个不与他互质的数li(i),同样预处理出ri(i)。当左端点由a(i)变为a(i+1)时,要将区间[i+1,ri(i)-1]的 f 值都减1,同理,如果存在j>i并且li(j)=i,那么就要将区间[i+1,ri(j)-1]的 f 值都加1。

代码如下(用树状数组维护):

  1. # include<iostream>
  2. # include<cstdio>
  3. # include<map>
  4. # include<set>
  5. # include<vector>
  6. # include<cstring>
  7. # include<algorithm>
  8. using namespace std;
  9.  
  10. const int N=200000;
  11.  
  12. struct Node
  13. {
  14. int id,l,r;
  15. };
  16. Node nde[N+1];
  17. int a[N+1];
  18. int li[N+1];
  19. int ri[N+1];
  20. int mark[N+1];
  21. int ans[N+1];
  22. int sum[N+1];
  23. vector<int>edge[N+1];
  24. vector<int>v[N+1];
  25. int n;
  26.  
  27. bool comp(const Node &a,const Node &b)
  28. {
  29. return a.l<b.l;
  30. }
  31.  
  32. void init()
  33. {
  34. for(int i=2;i<=N;++i)
  35. for(int j=i;j<=N;j+=i)
  36. v[j].push_back(i);
  37. }
  38.  
  39. int lowbit(int x)
  40. {
  41. return x&(-x);
  42. }
  43.  
  44. void add(int x,int val)
  45. {
  46. while(x>=1){
  47. sum[x]+=val;
  48. x-=lowbit(x);
  49. }
  50. }
  51.  
  52. int getSum(int x)
  53. {
  54. int res=0;
  55. while(x<=n){
  56. res+=sum[x];
  57. x+=lowbit(x);
  58. }
  59. return res;
  60. }
  61.  
  62. int main()
  63. {
  64. init();
  65. int m;
  66. while(scanf("%d%d",&n,&m)&&(n+m))
  67. {
  68. for(int i=1;i<=n;++i){
  69. scanf("%d",a+i);
  70. edge[i].clear();
  71. }
  72. memset(mark,0,sizeof(mark));
  73. for(int i=1;i<=n;++i){
  74. li[i]=0;
  75. for(int j=0;j<v[a[i]].size();++j){
  76. li[i]=max(li[i],mark[v[a[i]][j]]);
  77. mark[v[a[i]][j]]=i;
  78. }
  79. }
  80. memset(mark,1,sizeof(mark));
  81. for(int i=n;i>=1;--i){
  82. ri[i]=n+1;
  83. for(int j=0;j<v[a[i]].size();++j){
  84. ri[i]=min(ri[i],mark[v[a[i]][j]]);
  85. mark[v[a[i]][j]]=i;
  86. }
  87. }
  88.  
  89. memset(sum,0,sizeof(sum));
  90. for(int i=1;i<=n;++i){
  91. if(li[i]){
  92. edge[li[i]].push_back(i);
  93. }else{
  94. add(i,1);
  95. if(ri[i]<=n) add(ri[i],-1);
  96. }
  97. }
  98. for(int i=1;i<=m;++i){
  99. scanf("%d%d",&nde[i].l,&nde[i].r);
  100. nde[i].id=i;
  101. }
  102.  
  103. int id=1;
  104. sort(nde+1,nde+m+1,comp);
  105.  
  106. for(int i=1;i<=n&&id<=m;++i){
  107. while(nde[id].l==i){
  108. ans[nde[id].id]=(getSum(nde[id].l)-getSum(nde[id].r+1));
  109. ++id;
  110. }
  111. add(i,-1);
  112. if(ri[i]<=n) add(ri[i],1);
  113. for(int j=0;j<edge[i].size();++j){
  114. int x=edge[i][j];
  115. add(x,1);
  116. if(ri[x]<=n) add(ri[x],-1);
  117. }
  118. }
  119. for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
  120. }
  121. return 0;
  122. }

  

HDU-4777 Rabbit Kingdom(区间更新求和)的更多相关文章

  1. HDU 4777 Rabbit Kingdom(树状数组)

    HDU 4777 Rabbit Kingdom 题目链接 题意:给定一些序列.每次询问一个区间,求出这个区间和其它数字都互质的数的个数 #include <cstdio> #include ...

  2. HDU 4777 Rabbit Kingdom (2013杭州赛区1008题,预处理,树状数组)

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. HDU 1698 线段树 区间更新求和

    一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...

  4. HDU 4777 Rabbit Kingdom 树状数组

    分析:找到每一个点的左边离他最近的不互质数,记录下标(L数组),右边一样如此(R数组),预处理 这个过程需要分解质因数O(n*sqrt(n)) 然后离线,按照区间右端点排序 然后扫一遍,对于当前拍好顺 ...

  5. HDU 4777 Rabbit Kingdom --容斥原理+树状数组

    题意: 给一个数的序列,询问一些区间,问区间内与区间其他所有的数都互质的数有多少个. 解法: 直接搞有点难, 所谓正难则反,我们求区间内与其他随便某个数不互质的数有多少个,然后区间长度减去它就是答案了 ...

  6. HDU 4777 Rabbit Kingdom

    素因子分解,树状数组.$ACM/ICPC$ $2013$杭州区域赛$H$题. 首先需要处理出数字$a[i]$左边最远到$L[i]$,右边最远到$R[i]$区间内所有数字都与$a[i]$互质. 那么对于 ...

  7. hdu 4778 Rabbit Kingdom(减少国家)

    题目链接:hdu 4778 Rabbit Kingdom 题目大意:Alice和Bob玩游戏,有一个炉子.能够将S个同样颜色的宝石换成一个魔法石.如今有B个包,每一个包里有若干个宝石,给出宝石的颜色. ...

  8. hdu 1698 线段树 区间更新 区间求和

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)

    伸展数最基本操作的模板,区间求和,区间更新.为了方便理解,特定附上一自己搞的搓图 这是样例中的数据输入后建成的树,其中的1,2是加入的边界顶点,数字代表节点编号,我们如果要对一段区间[l, r]进行操 ...

  10. HDU(1698),线段树区间更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 区间更新重点在于懒惰标记. 当你更新的区间就是整个区间的时候,直接sum[rt] = c*(r- ...

随机推荐

  1. javaweb-四则运算

    这次作业,我们选择的是网页开发,后来我们小组才知道自己这方面的知识还是太匮乏了. 主要代码: public class calcu extends HttpServlet{ public void d ...

  2. win10 用微软账户登录无法访问共享的问题

    百度找了一大堆可以解决的,最终最简单的方式(可能是bug): 测试了一下,Win10用微软账户登录的,连局域网共享时,输入用户名的时候,前面加个乱七八糟的域名就可以访问了: 比如: 用户名:   ba ...

  3. Oracle GoldenGate 12c中的协同交付(Coordinated Delivery)

    OGG 12c中,并行交付有2种模式:集成交付.协同交付.不过集成交付只能针对目标端是oracle数据库(有版本要求)使用,而协同交付则可以在非oracle数据库上使用. 先来看2个问题, l 为什么 ...

  4. ODI中通过配置表和自定义逆向工程获取数据库信息

    自定义逆向工程RKM 从配置表meta_db, meta_table, meta_column, meta_key中获取生产库的元数据信息.

  5. 《JAVA学习笔记(14-10---14-11抽象类)》

    [14-10]面向对象-抽象类的产生 /* 描述狗,行为,吼叫. 描述狼,行为,吼叫. 发现他们之间有共性,可以进行向上抽取. 当然是抽取他们的所属共性类型,犬科. 犬科这类事物,都具备吼叫行为,但是 ...

  6. Jquery中的prop()方法 全选或全不选

    注意: prop()在高版本才会有效, 低版本用attr(); $(function(){ // 元素checkbox var aChecked = $('.checkGoods'); // 全选 v ...

  7. C++实现python标准库中的Counter

    看python standard library by exmple里面提到一个Counter容器,它像muliset一样,能够维持一个集合,并在常量时间插入元素.查询某个元素的个数,而且还提供了一个 ...

  8. UNIX 网络编程第三版

    第五章p102: ps -t  pts/6 -o pid,ppid,tty,stat,args,wchan 在我的系统上运行时出现:TTY not found linux发行版为mint17.1 改用 ...

  9. linux基础命令学习(三)Vim使用

    1. # vim 1.txt 命令模式: a i o A I O x X yy dd p G dw de h j k l f H M B a --- append 追加 在光标所在位置后追加一个字符 ...

  10. php大力力 [004节]PHP常量MAMP环境下加载网页

    我的问题是:“让mamp加载PHP文件”. 这个特别简单的问题,刚才也把我憋了几个钟头,唉....土啊,新学一个东西,学习成本就是高. 刚刚吃了好吃的南邵小龙虾,以及美味的八里桥大螃蟹,痛苦了半天,终 ...