花神游历各国(树状数组或线段树)
花神游历各国
Time Limit: 5 Sec Memory Limit: 128 MB[Submit][Status][Discuss]
Description
Input
Output
每次x=1时,每行一个整数,表示这次旅行的开心度
Sample Input
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
Sample Output
101
11
11
11
11
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9
//线段树的应用,因为就算 10^9 开6,7次根也变 1 了,所以用一个标记一下这区间是否开根结果不变了,即都是1或0,就能减少开根次数
1 /* *********************************************** 2 ┆ ┏┓ ┏┓ ┆ 3 ┆┏┛┻━━━┛┻┓ ┆ 4 ┆┃ ┃ ┆ 5 ┆┃ ━ ┃ ┆ 6 ┆┃ ┳┛ ┗┳ ┃ ┆ 7 ┆┃ ┃ ┆ 8 ┆┃ ┻ ┃ ┆ 9 ┆┗━┓ 马 ┏━┛ ┆ 10 ┆ ┃ 勒 ┃ ┆ 11 ┆ ┃ 戈 ┗━━━┓ ┆ 12 ┆ ┃ 壁 ┣┓┆ 13 ┆ ┃ 的草泥马 ┏┛┆ 14 ┆ ┗┓┓┏━┳┓┏┛ ┆ 15 ┆ ┃┫┫ ┃┫┫ ┆ 16 ┆ ┗┻┛ ┗┻┛ ┆ 17 ************************************************ */ 18 19 #include <stdio.h> 20 #include <string.h> 21 #include <math.h> 22 23 #define maxn 100002 24 typedef long long LL; 25 void sqr_tree_all(int left,int right,int k); 26 27 struct Node 28 { 29 int l,r; 30 LL data; 31 int e; 32 }node[4*maxn]; 33 34 int data[maxn]; 35 36 void InitTree(int left,int right,int k) 37 { 38 node[k].l=left; 39 node[k].r=right; 40 node[k].e=0; 41 if (left==right) 42 { 43 node[k].data=data[left]; 44 if (node[k].data==1||node[k].data==0) 45 node[k].e=1; 46 return; 47 } 48 int mid = (left+right)/2; 49 InitTree(left,mid,k*2); 50 InitTree(mid+1,right,k*2+1); 51 node[k].data=node[k*2].data+node[k*2+1].data; 52 if (node[k*2].e==1&&node[k*2+1].e==1) 53 node[k].e=1; 54 return; 55 } 56 57 LL enquir(int left,int right,int k) 58 { 59 if (left==node[k].l && right==node[k].r) 60 { 61 return node[k].data; 62 } 63 int mid =(node[k].l+node[k].r)/2; 64 if (right<=mid) return enquir(left,right,k*2);//说明在左区间 65 if (left>mid) return enquir(left,right,k*2+1); 66 return enquir(left,mid,2*k)+enquir(mid+1,right,2*k+1); 67 } 68 69 void sqr_tree(int left,int right,int k) 70 { 71 //如果这个区间开根号没效果了 72 if (node[k].e==1 && left>=node[k].l&&right<=node[k].r) 73 return ; 74 if (left==right&&left==node[k].l&&right==node[k].r)//必须找到叶节点才更新 75 { 76 node[k].data=sqrt(node[k].data); 77 if (node[k].data==1||node[k].data==0) 78 node[k].e=1; 79 return; 80 } 81 82 int mid = (node[k].l+node[k].r)/2; 83 if (right<=mid) 84 sqr_tree(left,right,k*2);//说明在左区间 85 else if (left>mid) 86 sqr_tree(left,right,k*2+1); 87 else 88 { 89 sqr_tree(left,mid,2*k); 90 sqr_tree(mid+1,right,2*k+1); 91 } 92 node[k].data=node[k*2].data + node[k*2+1].data; 93 if (node[k*2].e==1&&node[k*2+1].e==1) 94 node[k].e=1; 95 return; 96 } 97 98 int main() 99 { 100 int n; 101 while (scanf("%d",&n)!=EOF) 102 { 103 for (int i=1;i<=n;i++) 104 scanf("%d",&data[i]); 105 InitTree(1,n,1); 106 int m; 107 scanf("%d",&m); 108 int x,l,r; 109 while (m--) 110 { 111 scanf("%d%d%d",&x,&l,&r); 112 if (x==1) 113 { 114 LL ans = enquir(l,r,1); 115 printf("%lld\n",ans); 116 } 117 else 118 sqr_tree(l,r,1); 119 } 120 } 121 return 0; 122 }