XTUOJ 1238 Segment Tree

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!

  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\n",queryMin(x,y,1),queryMax(x,y,1));break;
116                 default:;
117             }
118         }
119     }
120     return 0;
121 }
View Code

 

posted @ 2015-06-14 13:30  狂徒归来  阅读(226)  评论(3编辑  收藏  举报