给n个数,m个询问, 问任意区间内与其它数互质的数有多少个

比如3个数1 2 4,询问[1,3] 那么答案是1

千万要记住,这样的题目,如果你不转变下,使劲往线段树想(虽然转变之后,也说要用到线段树,但是维护的东西不同了),那么会发现这样的题目,区间与区间之间是无法传递信息的,

区间与区间是无法传递信息的,区间与区间之间是无法传递信息的,重要的东西说三遍。

设n个数,存在数组a[]里面

我们预处理出,L[],和R[],L[i] 表示从i往左,第一个与a[i]不互质的数的位置+1,  R[i]表示从i往右,第一个与a[i]不互质的数的位置-1

即L[i] 表示 [L[i],i]内的所有数都与a[i]互质,R[i]表示[i,R[i]]内的所有数都与a[i]互质

然后我们离线处理,将所有的询问按照左端点排序

然后枚举左端点i,将所有L[j] = i的 [j,R[j]]区间+1,因为当左端点为i时,L[j]=i的数都在各自的有效区间[j,R[j]]里面生效了

当i=询问的区间的左端点时,只要查询右端点被加了多少次就行了。

走过i时,第i个数不再生效,所以将[i,R[i]]区间-1

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<string.h>
  4. #include<algorithm>
  5. #include <vector>
  6. using namespace std;
  7. const int N = + ;
  8. vector<int> prime[N];
  9. vector<int> cL[N];
  10. int a[N],L[N],R[N];
  11. int mark[N];
  12. int tree[N<<],lazy[N<<];
  13. int ans[N];
  14. void pushDown(int rt)
  15. {
  16. if(lazy[rt])
  17. {
  18. lazy[rt<<] += lazy[rt];
  19. lazy[rt<<|] += lazy[rt];
  20. tree[rt<<] += lazy[rt];
  21. tree[rt<<|] += lazy[rt];
  22. lazy[rt] = ;
  23. }
  24. }
  25. void update(int l, int r, int rt, int L, int R, int val)
  26. {
  27. if(L<=l && R>=r)
  28. {
  29. lazy[rt]+=val;
  30. tree[rt] += val;
  31. return;
  32. }
  33. pushDown(rt);
  34. int mid = (l+r)>>;
  35. if(L<=mid)
  36. update(l,mid,rt<<,L,R,val);
  37. if(R>mid)
  38. update(mid+,r,rt<<|,L,R,val);
  39.  
  40. }
  41. int query(int l, int r, int rt, int pos)
  42. {
  43. if(l==r)
  44. {
  45. return tree[rt];
  46. }
  47. pushDown(rt);
  48. int mid = (l+r)>>;
  49. if(pos<=mid)
  50. return query(l,mid,rt<<,pos);
  51. else
  52. return query(mid+,r,rt<<|,pos);
  53. }
  54. struct Node
  55. {
  56. int l,r,id;
  57. bool operator<(const Node&rhs)const
  58. {
  59. return l < rhs.l;
  60. }
  61. }q[N];
  62.  
  63. void getPrime()
  64. {
  65. for(int i=;i<=;++i)
  66. {
  67. if(!mark[i])
  68. for(int j=i;j<=;j+=i)
  69. {
  70. mark[j] = true;
  71. prime[j].push_back(i);//得到j的所有素数因子i
  72. }
  73. }
  74. }
  75. void init(int n)
  76. {
  77. memset(mark,,sizeof(mark));
  78. for(int i=; i<prime[a[]].size(); ++i)
  79. mark[prime[a[]][i]] = ;
  80. L[] = ;
  81. cL[].push_back();
  82. for(int i=;i<=n;++i)
  83. {
  84. int pos = ;
  85. for(int j=; j<prime[a[i]].size(); ++j)
  86. {
  87. pos = max(pos,mark[prime[a[i]][j]]);
  88. mark[prime[a[i]][j]] = i;
  89. }
  90. L[i] = pos + ;
  91. cL[L[i]].push_back(i);
  92. }
  93. for(int i=;i<N;++i)mark[i] = n + ;
  94. for(int i=;i<prime[a[n]].size(); ++i)
  95. mark[prime[a[n]][i]] = n;
  96. R[n] = n;
  97. for(int i=n-;i>=;--i)
  98. {
  99. int pos = n + ;
  100. for(int j=;j<prime[a[i]].size(); ++j)
  101. {
  102. pos = min(pos,mark[prime[a[i]][j]]);
  103. mark[prime[a[i]][j]] = i;
  104. }
  105. R[i] = pos - ;
  106. }
  107. }
  108. int main()
  109. {
  110. int n,m;
  111. getPrime();
  112. while(scanf("%d%d",&n,&m),n+m)
  113. {
  114. memset(tree,,sizeof(tree));
  115. memset(lazy,,sizeof(lazy));
  116. for(int i=;i<=n;++i)
  117. {
  118. scanf("%d",&a[i]);
  119. cL[i].clear();
  120. }
  121. init(n);
  122. for(int i=;i<m;++i)
  123. {
  124. scanf("%d%d",&q[i].l,&q[i].r);
  125. q[i].id = i;
  126. }
  127. sort(q,q+m);
  128. int cur = ;
  129. //枚举左端点
  130. for(int i=;i<=n;++i)
  131. {
  132. //当左端点为i时,使得所有L[j] = i的数都在各自的区间[j,R[j]]
  133. //所以在[j,R[j]]区间+1
  134. for(int j=;j<cL[i].size(); ++j)
  135. update(,n,,cL[i][j],R[cL[i][j]],);
  136. //当询问的左端点为i时,
  137. while(q[cur].l==i)
  138. {
  139. //只要询问右端点的值就行了,因为每个数都在自己能生效的区间里面+1了
  140. ans[q[cur].id] = query(,n,,q[cur].r);
  141. cur++;
  142. }
  143. //要走过第i个数了,所以第i个数不再生效了,所以将[i,R[i]]区间-1
  144. update(,n,,i,R[i],-);
  145. }
  146. for(int i=;i<m;++i)
  147. printf("%d\n",ans[i]);
  148. }
  149. return ;
  150. }

hdu(预处理+线段树)的更多相关文章

  1. hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  2. hdu 3974 线段树 将树弄到区间上

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  4. hdu 3397 线段树双标记

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

  6. hdu 4533 线段树(问题转化+)

    威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  7. hdu 2871 线段树(各种操作)

    Memory Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  8. hdu 4052 线段树扫描线、奇特处理

    Adding New Machine Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. hdu 1542 线段树扫描(面积)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

随机推荐

  1. ZenCoding Syntax

    语法: 后代:> 缩写:nav>ul>li 兄弟:+ 缩写:div+p+bq 上级:^ 缩写:div+div>p>span+em^bq 缩写:div+div>p&g ...

  2. Android学习-----如何使用sqlite对于后台数据交换,sqlite使用例程入门

     SQLite 这是一个非常流行的嵌入式数据库.它支持 SQL 查询,和只使用很少的内存.Android 在集成实施 SQLite,所以每 Android 应用程序能够使用 SQLite 数据库. ...

  3. maven项目配置Project Facets时further configuration available不出来问题

    如果下边的 further configuration available不出来 把Dynamic web module 去掉勾选,应用与项目,然后再点开项目的properties,再选中Dynami ...

  4. Web Api集成Swagger

    WebApi集成Swagger 1.新建一个WebApi空项目 2.新建一个Person实体类: public class Person { public int ID { get; set; } p ...

  5. Gulp.js简介

    Gulp.js简介 我们讨论了很多关于怎么减少页面体积,提高重网站性能的方法.有些是操作是一劳永逸的,如开启服务器的gzip压缩,使用适当的图片格式,或删除一些不必要的字符.但有一些任务是每次工作都必 ...

  6. Shell编程中Shift的用法(转)

    位置参数可以用shift命令左移.比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1.$2.$3丢弃,$0不移动.不带参数的shift命令相当于shift 1. 非常 ...

  7. 【编程之美】java二进制实现重建

    package com.cn.binarytree.utils; /** * @author 刘利娟 liulijuan132@gmail.com * @version 创建时间:2014年7月20日 ...

  8. Python 分析Twitter用户喜爱的推文

    CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-8-5 @author: guaguastd @name: an ...

  9. 在Windows下搭建React Native Android开发环境

    widows版本: win7 64位 专业版 1. 安装jdk.(我用的jdk7) 注意选择x86还是x64版本, 添加到系统PATH环境变量 2. 准备好android sdk 这个不多说,同时推荐 ...

  10. 北京联通100M光纤宽带需邀请函 实际速率12MB/S - OFweek光通讯网

    [新提醒]随身wifi无法使用FAQ(不断更新中~~~~~~) - 使用问题 - 360官方论坛 undefined 北京联通100M光纤宽带需邀请函 实际速率12MB/S - OFweek光通讯网 ...