线段树区间修改

Setv[]上来要全弄成负的。query里的sum别忘了加一。

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <cmath>
  6 using namespace std;
  7 const int maxn = 100000 + 10;
  8 const int maxn3 = maxn * 3;
  9 const int INF = -1u >> 1;
 10 int A[maxn], Minv[maxn3], Maxv[maxn3], Sumv[maxn3], Setv[maxn3];
 11 int v, ql, qr, _min, _max, _sum;
 12 int n, Q;
 13 char tp;
 14 void fresh(int o, int lc, int rc){
 15     Minv[o] = min(Minv[lc], Minv[rc]);
 16     Maxv[o] = max(Maxv[lc], Maxv[rc]);
 17     Sumv[o] = Sumv[lc] + Sumv[rc];
 18     return ;
 19 }
 20 void build(int o, int L, int R){
 21     if(L == R) Minv[o] = Maxv[o] = Sumv[o] = A[L];
 22     else{
 23         int M = L + R >> 1, lc = o << 1, rc = lc | 1;
 24         build(lc, L, M); build(rc, M + 1, R); fresh(o, lc, rc);
 25     }
 26     return ;
 27 }
 28 void pushdown(int o){
 29     if(Setv[o] >= 0){
 30         int lc = o << 1, rc = lc | 1;
 31         Setv[lc] = Setv[rc] = Setv[o];
 32         Setv[o] = -1;
 33     }
 34     return ;
 35 }
 36 void maintain(int o, int L, int R){
 37     if(Setv[o] >= 0){
 38         Minv[o] = Maxv[o] = Setv[o];
 39         Sumv[o] = (R - L + 1) * Setv[o];
 40     }
 41     else if(L < R) fresh(o, o << 1, (o << 1) | 1);
 42     return ;
 43 }
 44 void update(int o, int L, int R){
 45     if(ql <= L && R <= qr) Setv[o] = v;
 46     else{
 47         int M = L + R >> 1, lc = o << 1, rc = lc | 1;
 48         pushdown(o);
 49         if(ql <= M) update(lc, L, M); else maintain(lc, L, M);
 50         if(qr > M) update(rc, M + 1, R); else maintain(rc, M + 1, R);
 51     }
 52     maintain(o, L, R); return ;
 53 }
 54 void query(int o, int L, int R){
 55     if(Setv[o] >= 0){
 56         _min = min(_min, Setv[o]);
 57         _max = max(_max, Setv[o]);
 58         _sum += (min(R, qr) - max(L, ql) + 1) * Setv[o];
 59     }
 60     else if(ql <= L && R <= qr){
 61         _min = min(_min, Minv[o]);
 62         _max = max(_max, Maxv[o]);
 63         _sum += Sumv[o];
 64     }
 65     else{
 66         int M = L + R >> 1, lc = o << 1, rc = lc | 1;
 67         if(ql <= M) query(lc, L, M);
 68         if(qr > M) query(rc, M + 1, R);
 69     }
 70     return ;
 71 }
 72 void read(int &x){
 73     x = 0; int sig = 1; char ch = getchar();
 74     while(!isdigit(ch)) { if(ch == '-') sig = -1; ch = getchar(); }
 75     while(isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
 76     x *= sig; return ;
 77 }
 78 void read(char& x){
 79     x = getchar();
 80     while(!isalpha(x)) x = getchar();
 81     return ;
 82 }
 83 void init(){
 84     memset(Setv, -1, sizeof(Setv)); // !
 85     read(n);
 86     for(int i = 1; i <= n; i ++) read(A[i]);
 87     build(1, 1, n);
 88     read(Q);
 89     return ;
 90 }
 91 void work(){
 92     while(Q--)
 93     {
 94         char tp=getchar();
 95         while(!isalpha(tp)) tp=getchar();
 96         read(ql),read(qr);
 97         if(ql>qr) swap(ql,qr);
 98         if(tp=='Q')
 99         {
100             _sum=0; _min=INF; _max=-INF;
101             query(1,1,n);
102             printf("MaxNum: %d, MinNum: %d, Sum: %d\n",_max,_min,_sum);
103         }
104         else read(v),update(1,1,n);
105     }
106     return ;
107 }
108 void print(){
109 
110     return ;
111 }
112 int main(){
113     init();
114     work();
115     print();
116     return 0;
117 }

 

你可能感兴趣的:(线段树)