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

 

posted on 2017-11-18 23:06  xiaowuga  阅读(438)  评论(0编辑  收藏  举报

导航