您的位置:首页 > 其它

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判断。

ありがとうございます。

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

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: