题意:bc round 73 div1 D 中文题面

分析:注意到10^7之内的数最多phi O(log(n))次就会变成1,

因此可以考虑把一段相同的不为1的数缩成一个点,用平衡树来维护。

每次求phi的时候就在平衡树上取出这个区间然后暴力求phi,如果一段数变成了1,

就在平衡树里面删掉它,最后统计答案的时候只要把区间中被删去的1加回答案即可,

时间复杂度O((n + m)logn)

注:平衡树,写起来麻烦(然后其实我也不会写)

但是题解当中说把一段相同的数缩成一个点,就很好

所以用线段树,节点维护区间和以及(当这个区间元素都相同时)维护这个元素

然后操作2和操作3就是普通的线段树应用,区间更新以及区间求和

然后操作1,由于我维护了一整段相同元素的区间,所以更新时,

只要按照区间更新,区间在更新范围内,且节点所管辖区间的元素全部相同的时候,直接修改节点

区间更新就好了,这样的话,时间复杂度不是很高

由于单个元素的范围是1e7,所以先筛一遍欧拉函数

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. using namespace std;
  5. typedef long long LL;
  6. const int N = 1e7;
  7. const int maxn=3e5+;
  8. const LL mod = 1e9+;
  9. int phi[N+],n,m,T;
  10. int o[maxn<<],mark[maxn<<];
  11. LL sum[maxn<<];
  12. void pushup(int rt)
  13. {
  14. sum[rt]=sum[rt*]+sum[rt*+];
  15. if(o[rt*]==o[rt*+]&&o[rt*])
  16. o[rt]=o[rt*];
  17. else o[rt]=;
  18. }
  19. void pushdown(int rt,int l,int r)
  20. {
  21. if(mark[rt])
  22. {
  23. int mid=(l+r)>>;
  24. sum[rt*]=1ll*(LL)(mid-l+)*(LL)(mark[rt]);
  25. sum[rt*+]=1ll*(LL)(r-mid)*(LL)(mark[rt]);
  26. o[rt*]=o[rt*+]=mark[rt];
  27. mark[rt*]=mark[rt*+]=mark[rt];
  28. mark[rt]=;
  29. }
  30. }
  31. void build(int rt,int l,int r)
  32. {
  33. if(l==r)
  34. {
  35. scanf("%d",&o[rt]);
  36. sum[rt]=o[rt];
  37. return ;
  38. }
  39. int mid=(l+r)>>;
  40. build(rt*,l,mid);
  41. build(rt*+,mid+,r);
  42. pushup(rt);
  43. }
  44. void op1(int rt,int l,int r,int x,int y)
  45. {
  46. if(x<=l&&r<=y&&o[rt])
  47. {
  48. int tmp=phi[o[rt]];
  49. o[rt]=mark[rt]=tmp;
  50. sum[rt]=1ll*(LL)(r-l+)*(LL)(tmp);
  51. return;
  52. }
  53. pushdown(rt,l,r);
  54. int mid=(l+r)>>;
  55. if(x<=mid)op1(rt*,l,mid,x,y);
  56. if(y>mid)op1(rt*+,mid+,r,x,y);
  57. pushup(rt);
  58. }
  59. int t;
  60. void op2(int rt,int l,int r,int x,int y)
  61. {
  62. if(x<=l&&r<=y)
  63. {
  64. o[rt]=mark[rt]=t;
  65. sum[rt]=1ll*(LL)(r-l+)*(LL)(t);
  66. return;
  67. }
  68. pushdown(rt,l,r);
  69. int mid=(l+r)>>;
  70. if(x<=mid)op2(rt*,l,mid,x,y);
  71. if(y>mid)op2(rt*+,mid+,r,x,y);
  72. pushup(rt);
  73. }
  74. LL op3(int rt,int l,int r,int x,int y)
  75. {
  76. if(x<=l&&r<=y)
  77. return sum[rt];
  78. pushdown(rt,l,r);
  79. int mid=(l+r)>>;
  80. LL ans=;
  81. if(x<=mid)ans+=op3(rt*,l,mid,x,y);
  82. if(y>mid)ans+=op3(rt*+,mid+,r,x,y);
  83. return ans;
  84. }
  85. int main()
  86. {
  87. phi[]=;
  88. for(int i=; i<=N; ++i)
  89. {
  90. if(!phi[i])
  91. {
  92. for(int j=i; j<=N; j+=i)
  93. {
  94. if(!phi[j])
  95. phi[j]=j;
  96. phi[j]=phi[j]/i*(i-);
  97. }
  98. }
  99. }
  100. scanf("%d",&T);
  101. while(T--)
  102. {
  103. memset(o,,sizeof(o));
  104. memset(mark,,sizeof(mark));
  105. scanf("%d%d",&n,&m);
  106. build(,,n);
  107. while(m--)
  108. {
  109. int c,l,r;
  110. scanf("%d%d%d",&c,&l,&r);
  111. if(c==)scanf("%d",&t);
  112. if(c==)op1(,,n,l,r);
  113. else if(c==)op2(,,n,l,r);
  114. else printf("%I64d\n",op3(,,n,l,r));
  115. }
  116. }
  117. return ;
  118. }

HDU 5634 Rikka with Phi 线段树的更多相关文章

  1. HDU5634 Rikka with Phi 线段树

    // HDU5634 Rikka with Phi 线段树 // 思路:操作1的时候,判断一下当前区间是不是每个数都相等,在每个数相等的区间上操作.相当于lazy,不必更新到底. #include & ...

  2. HDU 5634 Rikka with Phi

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634 ------------------------------------------------ ...

  3. hdu 5828 Rikka with Sequence 线段树

    Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  4. HDU 6089 Rikka with Terrorist (线段树)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6089 题解 这波强行维护搞得我很懵逼... 扫描线,只考虑每个点能走到左上方(不包括正上方,但包括正左 ...

  5. Rikka with Phi 线段树

    Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds ...

  6. HDU 5828 Rikka with Sequence (线段树+剪枝优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...

  7. HDU 5828 Rikka with Sequence(线段树区间加开根求和)

    Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...

  8. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  9. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

随机推荐

  1. validate[.unobtrusive]和Bootstrap实现tooltip错误提示

    validate[.unobtrusive]和Bootstrap实现tooltip错误提示 类似的文章园子里已有,请看这里,个人感觉稍显复杂,日前也打算写一个简单的给项目用,一些关键点记录于此.最终效 ...

  2. maven3.1.1适合搭配的jdk版本

    maven 可以帮助我们管理项目的jar 不同的版本对jdk的要求也不相同, 比如3.1.1就要搭配1.6或以上的jre但是1.7有的版本还是会有点问题 当maven所需的jre版本不对应时项目会报错 ...

  3. net use命令详细解释

    1)建立空连接: net use \\IP\ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立非空连接: net use \ ...

  4. TWaver3D入门探索——3D拓扑图之人在江湖

    俗话说,有人的地方就有江湖,江湖就是帮派林立错综复杂的关系网.今天我们就来展示这样一个小小的江湖. 故事背景 崇祯末年,民不聊生,烽烟四起-- 江湖都是有背景的,我们的3D江湖也需要一个背景.江湖就是 ...

  5. 使用 Android Studio 跑新浪微博SDK Demo遇到的问题及解决

    概述 这是新浪微博官方 Android SDK Demo 使用 Android Studio 导入.编译并运行通过的版本. 源码:WeiboSdkDemo 官方项目请点击: weibo_android ...

  6. js 人工获取年月日

    var date = new Date(); var months = new Array("01", "02", "03", " ...

  7. Searching in a rotated and sorted array

    Given a sorted array that has been rotated serveral times. Write code to find an element in this arr ...

  8. JSON用法简介

    [JSON简介] jsoncpp 主要包含三种类型的 class:Value.Reader.Writer.jsoncpp 中所有对象.类名都在 namespace Json 中,包含 json.h 即 ...

  9. 如何在DJANGO里获取?带数据的东东,基于CBV

    用DEF的,有现成的,而用CLASS的,就要作一下变通. 如下: if self.request.GET: if self.request.GET.get('search_pk'): search_p ...

  10. spring 异常管理机制

    三.异常处理的几种实现: 3.1.在经典的三层架构模型中,通常都是这样来进行异常处理的: A.持久层一般抛出的是RuntiomeException类型的异常,一般不处理,直接向上抛出. B.业务层一般 ...