CodeVS4927 线段树练习5

题目描述 Description

有n个数和5种操作

add a b c:把区间[a,b]内的所有数都增加c

set a b c:把区间[a,b]内的所有数都设为c

sum a b:查询区间[a,b]的区间和

max a b:查询区间[a,b]的最大值

min a b:查询区间[a,b]的最小值

输入描述 Input Description

第一行两个整数n,m,第二行n个整数表示这n个数的初始值

接下来m行操作,同题目描述

输出描述 Output Description

对于所有的sum、max、min询问,一行输出一个答案

常规的线段树,6月22日就写好了代码,然后一直90分

直到今天师弟跟我说数据中有将一个区间全部改为0的情况……

解决方案是在线段树上的每一个点开一个boolean,判断这个点代表的区间是否被set操作更改,而不是直接根据标记是否等于0判断。

ありがとうございます。

作为一个高三狗在电脑室写代码感到莫名的惭愧。也是很久没有更新博客了。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #define rep(i,l,r) for(int i=l; i<=r; i++)
  6 #define clr(x,y) memset(x,y,sizeof(x))
  7 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
  8 using namespace std;
  9 typedef long long ll;
 10 typedef pair<int,int> pii;
 11 const int INF = 0x3f3f3f3f;
 12 const int maxn = 100010;
 13 inline ll read(){
 14     int ans = 0, f = 1; char c = getchar();
 15     for(; !isdigit(c); c = getchar()) if (c == '-') f = -1;
 16     for(; isdigit(c); c = getchar()) ans = ans * 10 + c - '0';
 17     return ans * f;
 18 }
 19 struct Node{
 20     int l,r;
 21     ll s,mn,mx,t1,t2;
 22     bool bl;
 23 }t[maxn<<2];
 24 int n,m,a,b,c,s[maxn];
 25 char op[10];
 26 inline void pushdown(int w){
 27     if (t[w].l == t[w].r) return;
 28     if (t[w].bl){
 29         t[w<<1].t1 = t[w].t1; t[w<<1|1].t1 = t[w].t1;
 30         t[w<<1].s = (t[w<<1].r - t[w<<1].l + 1) * t[w].t1;
 31         t[w<<1].mn = t[w<<1].mx = t[w].t1;
 32         t[w<<1|1].s = (t[w<<1|1].r - t[w<<1|1].l + 1) * t[w].t1;
 33         t[w<<1|1].mn = t[w<<1|1].mx = t[w].t1;
 34         t[w].t1 = 0; t[w].t2 = 0; t[w<<1].t2 = 0; t[w<<1|1].t2 = 0;
 35         t[w].bl = 0; t[w<<1].bl = 1; t[w<<1|1].bl = 1;
 36     }
 37     if (t[w].t2){
 38         if (t[w<<1].t1) t[w<<1].t1 += t[w].t2; else t[w<<1].t2 += t[w].t2;
 39         if (t[w<<1|1].t1) t[w<<1|1].t1 += t[w].t2; else t[w<<1|1].t2 += t[w].t2;
 40         t[w<<1].s += (t[w<<1].r - t[w<<1].l + 1) * t[w].t2;
 41         t[w<<1].mn += t[w].t2; t[w<<1].mx += t[w].t2;
 42         t[w<<1|1].s += (t[w<<1|1].r - t[w<<1|1].l + 1) * t[w].t2;
 43         t[w<<1|1].mn += t[w].t2; t[w<<1|1].mx += t[w].t2;
 44         t[w].t2 = 0;
 45     }
 46 }
 47 inline void maintain(int w){
 48     t[w].s = t[w<<1].s + t[w<<1|1].s;
 49     t[w].mx = max(t[w<<1].mx,t[w<<1|1].mx);
 50     t[w].mn = min(t[w<<1].mn,t[w<<1|1].mn);
 51 }
 52 void build(int u,int v,int w){
 53     t[w].l = u; t[w].r = v;
 54     if (u == v){
 55         t[w].mx = t[w].mn = t[w].s = s[u];
 56         t[w].t1 = t[w].t2 = 0;
 57         return;
 58     }
 59     int mid = (u + v) >> 1;
 60     build(u,mid,w<<1); build(mid+1,v,w<<1|1);
 61     maintain(w);
 62 }
 63 void modify(int u,int v,int w,ll x,int T){
 64     pushdown(w);
 65     if (t[w].l == u && t[w].r == v){
 66         if (T == 1){
 67             t[w].t1 = x; t[w].t2 = 0;
 68             t[w].s = (t[w].r - t[w].l + 1) * x;
 69             t[w].mn = t[w].mx = x; t[w].bl = 1;
 70         }
 71         else{
 72             if (t[w].t1) t[w].t1 += x; else t[w].t2 += x;
 73             t[w].s += (t[w].r - t[w].l + 1) * x;
 74             t[w].mn += x; t[w].mx += x;
 75         }
 76         return;
 77     }
 78     int mid = (t[w].l + t[w].r) >> 1;
 79     if (v <= mid) modify(u,v,w<<1,x,T);
 80     else if (u > mid) modify(u,v,w<<1|1,x,T);
 81     else{
 82         modify(u,mid,w<<1,x,T);
 83         modify(mid+1,v,w<<1|1,x,T);
 84     }
 85     maintain(w);
 86 }
 87 ll query(int u,int v,int w,int T){
 88     pushdown(w);
 89     if (t[w].l == u && t[w].r == v){
 90         if (T == 1) return t[w].s;
 91         else if (T == 2) return t[w].mx; else return t[w].mn;
 92     }
 93     int mid = (t[w].l + t[w].r) >> 1;
 94     if (v <= mid) return query(u,v,w<<1,T);
 95     else if (u > mid) return query(u,v,w<<1|1,T);
 96     else{
 97         if (T == 1) return query(u,mid,w<<1,T) + query(mid+1,v,w<<1|1,T);
 98         else if (T == 2) return max(query(u,mid,w<<1,T),query(mid+1,v,w<<1|1,T));
 99         else return min(query(u,mid,w<<1,T),query(mid+1,v,w<<1|1,T));
100     }
101 }
102 int main(){
103     n = read(); m = read();
104     rep(i,1,n) s[i] = read();
105     build(1,n,1);
106     rep(i,1,m){
107         scanf("%s",op); a = read(); b = read();
108         if (op[0] == 'a'){
109             c = read();
110             modify(a,b,1,c,2);
111         }
112         else if (op[0] == 's' && op[1] == 'e'){
113             c = read();
114             modify(a,b,1,c,1);
115         }
116         else if (op[0] == 's' && op[1] == 'u') printf("%lld
",query(a,b,1,1));
117         else if (op[0] == 'm' && op[1] == 'a') printf("%lld
",query(a,b,1,2));
118         else if (op[0] == 'm' && op[1] == 'i') printf("%lld
",query(a,b,1,3));
119     }
120     return 0;
121 }
View Code
原文地址:https://www.cnblogs.com/jimzeng/p/codevs4927.html