uoj#228. 基础数据结构练习题(线段树区间开方)
题目链接:http://uoj.ac/problem/228
代码:(先开个坑在这个地方)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+7; 4 long long a[N]; 5 struct node{ 6 int l,r; 7 long long maxx,minn,sum; 8 long long lazy; 9 void up(long long val){ 10 maxx+=val;minn+=val;sum+=(r-l+1)*1ll*val; 11 lazy+=val; 12 } 13 }tree[8*N]; 14 void push_up(int x){ 15 tree[x].maxx=max(tree[x<<1].maxx,tree[x<<1|1].maxx); 16 tree[x].minn=min(tree[x<<1].minn,tree[x<<1|1].minn); 17 tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum; 18 } 19 void push_down(int x){ 20 long long val=tree[x].lazy; 21 if(val){ 22 tree[x<<1].up(val); 23 tree[x<<1|1].up(val); 24 tree[x].lazy=0; 25 } 26 } 27 void build(int x,int l,int r){ 28 tree[x].l=l; tree[x].r=r; 29 tree[x].lazy=tree[x].sum=0; 30 if(l==r){ 31 tree[x].minn=tree[x].maxx=tree[x].sum=a[l]; 32 return; 33 } 34 int m=(l+r)/2; 35 build(x<<1,l,m); 36 build(x<<1|1,m+1,r); 37 push_up(x); 38 } 39 void updata(int x,int l,int r,long long val){ 40 int L=tree[x].l,R=tree[x].r; 41 if(l<=L&&R<=r){ 42 tree[x].up(val);return; 43 } 44 int m=(L+R)/2; 45 push_down(x); 46 if(l<=m) updata(x<<1,l,r,val); 47 if(r>m) updata(x<<1|1,l,r,val); 48 push_up(x); 49 } 50 void Sqrt(int x,int l,int r){ 51 push_down(x); 52 int L=tree[x].l,R=tree[x].r; 53 if(l<=L&&R<=r){ 54 if(tree[x].maxx==tree[x].minn){ 55 long long t=(long long)sqrt(tree[x].maxx); 56 updata(x,L,R,t-tree[x].maxx); 57 return; 58 } 59 else if(tree[x].minn+1==tree[x].maxx){ 60 long long t1=(long long)sqrt(tree[x].minn); 61 long long t2=(long long)sqrt(tree[x].maxx); 62 if(t1+1==t2){ 63 updata(x,L,R,t2-tree[x].maxx); 64 return; 65 } 66 } 67 } 68 int m=(L+R)/2; 69 if(l<=m) Sqrt(x<<1,l,r); 70 if(r>m) Sqrt(x<<1|1,l,r); 71 push_up(x); 72 } 73 long long query(int x,int l,int r){ 74 push_down(x); 75 int L=tree[x].l,R=tree[x].r; 76 if(l<=L&&R<=r){ 77 return tree[x].sum; 78 } 79 int m=(L+R)/2; 80 long long ans=0; 81 if(l<=m) ans+=query(x<<1,l,r); 82 if(r>m) ans+=query(x<<1|1,l,r); 83 push_up(x); 84 return ans; 85 } 86 int main(){ 87 int n,m; 88 scanf("%d%d",&n,&m); 89 for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 90 build(1,1,n); 91 while(m--){ 92 int op,l,r; 93 scanf("%d%d%d",&op,&l,&r); 94 if(op==1){ 95 long long val; 96 scanf("%lld",&val); 97 updata(1,l,r,val); 98 } 99 else if(op==2){ 100 Sqrt(1,l,r); 101 } 102 else{ 103 printf("%lld\n",query(1,l,r)); 104 } 105 } 106 return 0; 107 }