BZOJ-3211-花神游历各国(线段树)

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

 

Source

SPOJ2713 gss4 数据已加强

 

题解

这道题和以前考的一道题差不多(那道题是区间取模)

这道题是区间开根,和取模相似的,开根次数也是有限的,所以我们可以用线段树来维护一段区间,当区间内都是0或1的时候就不用再做了

 1 #include<bits/stdc++.h>
 2 #define N 100005
 3 #define ll long long
 4 using namespace std;
 5 int n,m;
 6 int a[N];
 7 ll tree[4*N];
 8 bool flag[4*N];
 9 inline int read(){
10     int x=0,f=1; char ch=getchar();
11     while (ch>'9'||ch<'0'){ if (ch=='-') f=-1; ch=getchar(); }
12     while (ch<='9'&&ch>='0'){ x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }
13     return x*f;
14 }
15 void update(int v){
16     tree[v]=tree[v<<1]+tree[v<<1|1];
17     flag[v]=flag[v<<1]&flag[v<<1|1];
18 }
19 void build(int v,int l,int r){
20     if (l==r){
21         tree[v]=a[l];
22         if (a[l]<=1) flag[v]=1;
23         return;
24     }
25     int mid=(l+r)>>1;
26     build(v<<1,l,mid);
27     build(v<<1|1,mid+1,r);
28     update(v);
29 } 
30 ll query(int v,int l,int r,int x,int y){
31     if (x<=l&&y>=r) return tree[v];
32     int mid=(l+r)>>1;
33     if (y<=mid) return query(v<<1,l,mid,x,y); else
34     if (x>mid) return query(v<<1|1,mid+1,r,x,y); else
35     return query(v<<1,l,mid,x,mid)+query(v<<1|1,mid+1,r,mid+1,y);
36 }
37 void change(int v,int l,int r,int x,int y){
38     if (x<=l&&y>=r&&flag[v]) return;
39     if (l==r){
40         tree[v]=(ll)sqrt(tree[v]);
41         if (tree[v]<=1) flag[v]=1;
42         return;
43     }
44     int mid=(l+r)>>1;
45     if (y<=mid) change(v<<1,l,mid,x,y); else
46     if (x>mid) change(v<<1|1,mid+1,r,x,y); else{
47         change(v<<1,l,mid,x,mid);
48         change(v<<1|1,mid+1,r,mid+1,y); 
49     }
50     update(v);
51 }
52 int main(){
53     n=read();
54     for (int i=1;i<=n;i++) a[i]=read();
55     build(1,1,n);
56     m=read();
57     for (int i=1;i<=m;i++){
58         int x=read(),l=read(),r=read();
59         if (x==1) printf("%lld\n",query(1,1,n,l,r));
60             else change(1,1,n,l,r);
61     }
62     return 0;
63 }
View Code

 

转载于:https://www.cnblogs.com/zhuchenrui/p/7812801.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值