Segment Tree
Accepted : 3 Submit : 21
Time Limit : 9000 MS Memory Limit : 65536 KB
Problem Description:
A contest is not integrity without problems about data structure.
There is an array a[1],a[2],…,a[n]. And q questions of the following 4 types:
1 l r c - Update a[k] with a[k]+c for all l≤k≤r
2 l r c - Update a[k] with min{a[k],c} for all l≤k≤r;
3 l r c - Update a[k] with max{a[k],c} for all l≤k≤r;
4 l r - Ask for min{a[k]:l≤k≤r} and max{a[k]:l≤k≤r}.
Input
The first line contains a integer T(no more than 5) which represents the number of test cases.
For each test case, the first line contains 2 integers n,q (1≤n,q≤200000).
The second line contains n integers a1,a2,…,an which indicates the initial values of the array (|ai|≤).
Each of the following q lines contains an integer t which denotes the type of i-th question. If t=1,2,3, 3 integers l,r,c follows. If t=4, 2 integers l,r follows. (1≤ti≤4,1≤li≤ri≤n)
If t=1, |ci|≤2000;
If t=2,3, |ci|≤10^9.
Output
For each question of type 4, output two integers denote the minimum and the maximum.
Sample Input
1
1 1
1
4 1 1
Sample Output
1 1
解题:如其名,线段树!关键在于如何解决矛盾,既要相加,又要进行区间重置?那么这样搞,如何进行lazy呢?只要设置一个重置标志就好了。
BB is cheap!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 200010; 4 struct node { 5 int lt,rt,theMin,theMax,add,lazy; 6 bool reset; 7 } tree[maxn<<2]; 8 void pushup(int v) { 9 tree[v].theMax = max(tree[v<<1].theMax,tree[v<<1|1].theMax); 10 tree[v].theMin = min(tree[v<<1].theMin,tree[v<<1|1].theMin); 11 } 12 void pushdown(int v) { 13 if(tree[v].reset){ 14 tree[v].reset = false; 15 tree[v<<1].reset = tree[v<<1|1].reset = true; 16 tree[v<<1].lazy = tree[v<<1|1].lazy = tree[v].lazy; 17 tree[v<<1].theMin = tree[v<<1].theMax = tree[v].lazy; 18 tree[v<<1|1].theMin = tree[v<<1|1].theMax = tree[v].lazy; 19 tree[v<<1].add = tree[v<<1|1].add = 0; 20 //cout<<tree[v].lt<<" "<<tree[v].rt<<" "<<tree[v].lazy<<" nmb"<<endl; 21 } 22 if(tree[v].add){ 23 tree[v<<1].add += tree[v].add; 24 tree[v<<1|1].add += tree[v].add; 25 tree[v<<1].theMax += tree[v].add; 26 tree[v<<1].theMin += tree[v].add; 27 tree[v<<1|1].theMax += tree[v].add; 28 tree[v<<1|1].theMin += tree[v].add; 29 tree[v].add = 0; 30 } 31 } 32 void build(int lt,int rt,int v) { 33 tree[v].lt = lt; 34 tree[v].rt = rt; 35 tree[v].reset = false; 36 tree[v].add = 0; 37 if(lt == rt) { 38 scanf("%d",&tree[v].theMin); 39 tree[v].theMax = tree[v].theMin; 40 return; 41 } 42 int mid = (lt + rt)>>1; 43 build(lt,mid,v<<1); 44 build(mid+1,rt,v<<1|1); 45 pushup(v); 46 } 47 int queryMax(int lt,int rt,int v) { 48 if(lt <= tree[v].lt && rt >= tree[v].rt) return tree[v].theMax; 49 pushdown(v); 50 int theMax = INT_MIN; 51 if(lt <= tree[v<<1].rt) theMax = max(theMax,queryMax(lt,rt,v<<1)); 52 if(rt >= tree[v<<1|1].lt) theMax = max(theMax,queryMax(lt,rt,v<<1|1)); 53 pushup(v); 54 return theMax; 55 } 56 int queryMin(int lt,int rt,int v) { 57 if(lt <= tree[v].lt && rt >= tree[v].rt) return tree[v].theMin; 58 pushdown(v); 59 int theMin = INT_MAX; 60 if(lt <= tree[v<<1].rt) theMin = min(theMin,queryMin(lt,rt,v<<1)); 61 if(rt >= tree[v<<1|1].lt) theMin = min(theMin,queryMin(lt,rt,v<<1|1)); 62 pushup(v); 63 return theMin; 64 } 65 void add(int lt,int rt,int val,int v) { 66 if(lt <= tree[v].lt && rt >= tree[v].rt) { 67 tree[v].add += val; 68 tree[v].theMax += val; 69 tree[v].theMin += val; 70 return; 71 } 72 pushdown(v); 73 if(lt <= tree[v<<1].rt) add(lt,rt,val,v<<1); 74 if(rt >= tree[v<<1|1].lt) add(lt,rt,val,v<<1|1); 75 pushup(v); 76 } 77 void updateMax(int lt,int rt,int val,int v) { 78 if(lt <= tree[v].lt && rt >= tree[v].rt && tree[v].theMax <= val) { 79 tree[v].reset = true; 80 tree[v].theMax = tree[v].theMin = val; 81 tree[v].lazy = val; 82 tree[v].add = 0; 83 return; 84 }else if(lt <= tree[v].lt && rt >= tree[v].rt && val <= tree[v].theMin) return; 85 pushdown(v); 86 if(lt <= tree[v<<1].rt) updateMax(lt,rt,val,v<<1); 87 if(rt >= tree[v<<1|1].lt) updateMax(lt,rt,val,v<<1|1); 88 pushup(v); 89 } 90 void updateMin(int lt,int rt,int val,int v) { 91 if(lt <= tree[v].lt && rt >= tree[v].rt && tree[v].theMin >= val){ 92 tree[v].add = 0; 93 tree[v].reset = true; 94 tree[v].theMax = tree[v].theMin = val; 95 tree[v].lazy = val; 96 return; 97 }else if(lt <= tree[v].lt && rt >= tree[v].rt && tree[v].theMax <= val) return; 98 pushdown(v); 99 if(lt <= tree[v<<1].rt) updateMin(lt,rt,val,v<<1); 100 if(rt >= tree[v<<1|1].lt) updateMin(lt,rt,val,v<<1|1); 101 pushup(v); 102 } 103 int main() { 104 int n,q,op,x,y,c,T; 105 scanf("%d",&T); 106 while(T--){ 107 scanf("%d %d",&n,&q); 108 build(1,n,1); 109 while(q--){ 110 scanf("%d%d%d",&op,&x,&y); 111 switch(op){ 112 case 1:scanf("%d",&c);add(x,y,c,1);break; 113 case 2:scanf("%d",&c);updateMin(x,y,c,1);break; 114 case 3:scanf("%d",&c);updateMax(x,y,c,1);break; 115 case 4:printf("%d %d ",queryMin(x,y,1),queryMax(x,y,1));break; 116 default:; 117 } 118 } 119 } 120 return 0; 121 }