花神游历各国(树状数组或线段树)

花神游历各国

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

Sample Output

101

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 }
View Code

 

posted @ 2016-10-30 21:21  happy_codes  阅读(114)  评论(0编辑  收藏  举报