buaa2014校赛 1088 再也不会依赖任何人了----线段树

前端之家收集整理的这篇文章主要介绍了buaa2014校赛 1088 再也不会依赖任何人了----线段树前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Description

"任何人都不相信未来,任何人也都无法接受未来。
既然这样,那么我再也不会依赖任何人了,也没必要让任何人理解。"
"所有的魔女,都由我一人来解决!" homura默言。

现在有一个数字序列,要对这个序列进行实时修改与询问。
·修改是把一段区间内所有数字都平方。
·询问是询问一段区间内数字和的平方。

但是询问的结果会非常非常大,所以只需要这个数对61取模的结果即可。

Input

输入文件包含多组数据,以EOF为结尾。
对于每组数据第一行有两个正整数n和m,n代表序列的元素数目,m代表操作/询问个数。
接下来一行有n个非负整数,表示原序列。
接下来有m行,每行由以下两种情况构成。
·S L R 表示把[L,R]这段区间内所有数字都平方一下,
·Q L R 表示询问[L,R]这段区间的和的平方。

1≤n≤100,000,1≤m≤100,000,0≤序列内元素<230,1≤L≤R≤n 。

Output

对于每个询问输出一行表示对应的结果。

Sample Input

  1. 5 3
  2. 1 2 3 4 5
  3. Q 1 5
  4. S 1 5
  5. Q 1 5

Sample Output

  1. 42
  2. 36

Hint

对于第一个询问,结果为225,输出42
对于第二个询问,结果为3025,输出36

Author: Zhao XuanAng


a^60 = 1 (mod 61)

a^64 = a^4 (mod 61)

因此产生循环节

lazy表示,区间做了几次数的平方的操作

a^64,(6次操作) == a^4 (2次操作)

然后线段树。。

  1. #include <iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<stdlib.h>
  5. #include<math.h>
  6. #include<algorithm>
  7. using namespace std;
  8. #define ll long long
  9. #define mem(a,b) memset(a,b,sizeof(a))
  10. #define inf 0x3f3f3f
  11.  
  12. int trans[6]={1,2,3,4,5,2};
  13. int tran[4][6]=
  14. {
  15. {2,3},{3,4},{4,5},{5,2}
  16. };
  17. struct node
  18. {
  19. int l,r,lazy;
  20. int s[6];
  21. int mid()
  22. {
  23. return (l+r)>>1;
  24. }
  25. }tree[4*100010];
  26. int p[100010];
  27.  
  28. int tmp[6];
  29. void process(int id,int t)
  30. {
  31. if(t==0) return ;
  32. if(t==1)
  33. {
  34. for(int i=0;i<6;i++)
  35. tmp[i]=tree[id].s[trans[i]];
  36. }
  37. else
  38. {
  39. t=(t-2)%4;
  40. for(int i=0;i<6;i++)
  41. tmp[i]=tree[id].s[tran[t][i]];
  42. }
  43. for(int i=0;i<6;i++)
  44. tree[id].s[i]=tmp[i];
  45. }
  46. void pushup(int id)
  47. {
  48. for(int i=0;i<6;i++)
  49. tree[id].s[i]=(tree[id<<1].s[i]+tree[id<<1|1].s[i])%61;
  50. }
  51. void pushdown(int id)
  52. {
  53. if(tree[id].lazy)
  54. {
  55. tree[id<<1].lazy+=tree[id].lazy;
  56. tree[id<<1|1].lazy+=tree[id].lazy;
  57. process(id<<1,tree[id].lazy);
  58. process(id<<1|1,tree[id].lazy);
  59. tree[id].lazy=0;
  60. }
  61. }
  62. void build(int id,int x,int y)
  63. {
  64. tree[id].l=x;
  65. tree[id].r=y;
  66. tree[id].lazy=0;
  67. if(x==y)
  68. {
  69. int val=p[x];
  70. for(int i=0;i<6;i++)
  71. {
  72. tree[id].s[i]=val;
  73. val=val*val%61;
  74. }
  75. return ;
  76. }
  77. int mid=tree[id].mid();
  78. build(id<<1,x,mid);
  79. build(id<<1|1,mid+1,y);
  80. pushup(id);
  81. }
  82. void change(int id,int y)
  83. {
  84. if(tree[id].l==x && tree[id].r==y)
  85. {
  86. tree[id].lazy++;
  87. process(id,1);
  88. return ;
  89. }
  90. pushdown(id);
  91. int mid=tree[id].mid();
  92. if(y<=mid)
  93. change(id<<1,y);
  94. else if(x>=mid+1)
  95. change(id<<1|1,y);
  96. else
  97. {
  98. change(id<<1,mid);
  99. change(id<<1|1,y);
  100. }
  101. pushup(id);
  102. }
  103. int query(int id,int y)
  104. {
  105. if(tree[id].l==x && tree[id].r==y)
  106. {
  107. return tree[id].s[0];
  108. }
  109. pushdown(id);
  110. int mid=tree[id].mid();
  111. if(y<=mid)
  112. return query(id<<1,y);
  113. else if(x>=mid+1)
  114. return query(id<<1|1,y);
  115. else
  116. return (query(id<<1,mid)+query(id<<1|1,y))%61;
  117. }
  118. int main()
  119. {
  120. int n,m,i,j,k;
  121. while(scanf("%d%d",&n,&m)!=EOF)
  122. {
  123. for(i=1;i<=n;i++)
  124. {
  125. scanf("%d",&p[i]);
  126. p[i]%=61;
  127. }
  128. build(1,1,n);
  129. char ch[4];
  130. while(m--)
  131. {
  132. scanf("%s",ch);
  133. int a,b;
  134. scanf("%d%d",&a,&b);
  135. if(ch[0]=='S')
  136. {
  137. change(1,a,b);
  138. }
  139. else
  140. {
  141. int ans=query(1,b);
  142. ans=ans*ans%61;
  143. printf("%d\n",ans);
  144. }
  145. }
  146. }
  147. }

猜你在找的设计模式相关文章