CodeVS4927 线段树练习5
2016-08-08 14:06
423 查看
题目描述 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判断。
ありがとうございます。
作为一个高三狗在电脑室写代码感到莫名的惭愧。也是很久没有更新博客了。
View Code
有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判断。
ありがとうございます。
作为一个高三狗在电脑室写代码感到莫名的惭愧。也是很久没有更新博客了。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define rep(i,l,r) for(int i=l; i<=r; i++) #define clr(x,y) memset(x,y,sizeof(x)) #define travel(x) for(Edge *p=last[x]; p; p=p->pre) using namespace std; typedef long long ll; typedef pair<int,int> pii; const int INF = 0x3f3f3f3f; const int maxn = 100010; inline ll read(){ int ans = 0, f = 1; char c = getchar(); for(; !isdigit(c); c = getchar()) if (c == '-') f = -1; for(; isdigit(c); c = getchar()) ans = ans * 10 + c - '0'; return ans * f; } struct Node{ int l,r; ll s,mn,mx,t1,t2; bool bl; }t[maxn<<2]; int n,m,a,b,c,s[maxn]; char op[10]; inline void pushdown(int w){ if (t[w].l == t[w].r) return; if (t[w].bl){ t[w<<1].t1 = t[w].t1; t[w<<1|1].t1 = t[w].t1; t[w<<1].s = (t[w<<1].r - t[w<<1].l + 1) * t[w].t1; t[w<<1].mn = t[w<<1].mx = t[w].t1; t[w<<1|1].s = (t[w<<1|1].r - t[w<<1|1].l + 1) * t[w].t1; t[w<<1|1].mn = t[w<<1|1].mx = t[w].t1; t[w].t1 = 0; t[w].t2 = 0; t[w<<1].t2 = 0; t[w<<1|1].t2 = 0; t[w].bl = 0; t[w<<1].bl = 1; t[w<<1|1].bl = 1; } if (t[w].t2){ if (t[w<<1].t1) t[w<<1].t1 += t[w].t2; else t[w<<1].t2 += t[w].t2; if (t[w<<1|1].t1) t[w<<1|1].t1 += t[w].t2; else t[w<<1|1].t2 += t[w].t2; t[w<<1].s += (t[w<<1].r - t[w<<1].l + 1) * t[w].t2; t[w<<1].mn += t[w].t2; t[w<<1].mx += t[w].t2; t[w<<1|1].s += (t[w<<1|1].r - t[w<<1|1].l + 1) * t[w].t2; t[w<<1|1].mn += t[w].t2; t[w<<1|1].mx += t[w].t2; t[w].t2 = 0; } } inline void maintain(int w){ t[w].s = t[w<<1].s + t[w<<1|1].s; t[w].mx = max(t[w<<1].mx,t[w<<1|1].mx); t[w].mn = min(t[w<<1].mn,t[w<<1|1].mn); } void build(int u,int v,int w){ t[w].l = u; t[w].r = v; if (u == v){ t[w].mx = t[w].mn = t[w].s = s[u]; t[w].t1 = t[w].t2 = 0; return; } int mid = (u + v) >> 1; build(u,mid,w<<1); build(mid+1,v,w<<1|1); maintain(w); } void modify(int u,int v,int w,ll x,int T){ pushdown(w); if (t[w].l == u && t[w].r == v){ if (T == 1){ t[w].t1 = x; t[w].t2 = 0; t[w].s = (t[w].r - t[w].l + 1) * x; t[w].mn = t[w].mx = x; t[w].bl = 1; } else{ if (t[w].t1) t[w].t1 += x; else t[w].t2 += x; t[w].s += (t[w].r - t[w].l + 1) * x; t[w].mn += x; t[w].mx += x; } return; } int mid = (t[w].l + t[w].r) >> 1; if (v <= mid) modify(u,v,w<<1,x,T); else if (u > mid) modify(u,v,w<<1|1,x,T); else{ modify(u,mid,w<<1,x,T); modify(mid+1,v,w<<1|1,x,T); } maintain(w); } ll query(int u,int v,int w,int T){ pushdown(w); if (t[w].l == u && t[w].r == v){ if (T == 1) return t[w].s; else if (T == 2) return t[w].mx; else return t[w].mn; } int mid = (t[w].l + t[w].r) >> 1; if (v <= mid) return query(u,v,w<<1,T); else if (u > mid) return query(u,v,w<<1|1,T); else{ if (T == 1) return query(u,mid,w<<1,T) + query(mid+1,v,w<<1|1,T); else if (T == 2) return max(query(u,mid,w<<1,T),query(mid+1,v,w<<1|1,T)); else return min(query(u,mid,w<<1,T),query(mid+1,v,w<<1|1,T)); } } int main(){ n = read(); m = read(); rep(i,1,n) s[i] = read(); build(1,n,1); rep(i,1,m){ scanf("%s",op); a = read(); b = read(); if (op[0] == 'a'){ c = read(); modify(a,b,1,c,2); } else if (op[0] == 's' && op[1] == 'e'){ c = read(); modify(a,b,1,c,1); } else if (op[0] == 's' && op[1] == 'u') printf("%lld\n",query(a,b,1,1)); else if (op[0] == 'm' && op[1] == 'a') printf("%lld\n",query(a,b,1,2)); else if (op[0] == 'm' && op[1] == 'i') printf("%lld\n",query(a,b,1,3)); } return 0; }
View Code
相关文章推荐
- <线段树系列4> codevs 4927 线段树练习5
- Codevs 4927 线段树练习5(分块)
- codevs 4927 线段树练习5
- 线段树练习5(codevs 4927)
- 【codevs 1080】线段树练习
- CodeVS4919 线段树练习4
- codevs1080线段树练习(zkw线段树)
- codevs4919 线段树练习4
- codevs 1080 线段树练习
- 【codevs 1080~1082】线段树练习重做
- codevs 1082 线段树练习 3
- [CodeVS1081]线段树练习2(区间修改+单点询问)
- 【codevs3304】水果姐逛水果店Ⅰ,线段树练习
- codevs 1081 线段树练习 2 线段树
- 线段树模版(codevs1081线段树练习2)
- CODE[VS] 1080 线段树练习(单值修改、区间求和)
- codevs 1080 线段树练习--用树状数组做的
- Code Vs 1082 线段树练习 3
- 【CodeVS】1080 线段树练习 分块 线段树 树状数组 开放性
- [CODEVS1082]线段树练习 3