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!

XTUOJ 1238 Segment Tree
  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

 

你可能感兴趣的:(tree)