時間限制: 1 s
空間限制: 128000 kb
題目等級 : ** gold
題解檢視執行結果
有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詢問,一行輸出乙個答案
樣例輸入 sample input
10 6
3 9 2 8 1 7 5 0 4 6
add 4 9 4
set 2 6 2
add 3 8 2
sum 2 10
max 1 7
min 3 6
樣例輸出 sample output
資料範圍及提示 data size & hint
10%:130%:1100%:1保證中間結果在long long(c/c++)、int64(pascal)範圍內
ps:由於資料6出錯導致某些人只有90分,已於2016.5.13修正。
出題人在此對兩位90分的使用者表示誠摯的歉意
好噁心的一道題
這道題特殊在set操作
對於這個操作,我們需要增加兩個變數來維護,乙個維護這個區間是否被修改,乙個維護被修改成了多少
特別注意不能只維護被修改成了多少(會有0的情況)
在下傳標記的時候,需要先下傳set標記,再下傳add標記
因為我們在設定set標記的時候已經把add標記置為0
如果此時add標記不為0,就說明這個標記一定是在set標記設定之後設定的
再注意一下細節就可以了
1 #include2 #include3 #include4 #include5#define ll long long
6#define ls k<<1
7#define rs k<<1|1
8using
namespace
std;
9const ll maxn=400400;10
const ll inf =0x7fffff
;11 inline void read(ll &n)
1217
struct
node
18tree[maxn];
22ll n,m;
23 ll ans=0
;24 inline void
update(ll k)
2530
void
build_tree(ll ll,ll rr,ll k)
3140 ll mid=tree[k].l+tree[k].r>>1;41
build_tree(ll,mid,ls);
42 build_tree(mid+1
,rr,rs);
43update(k);44}
45void
down(ll k)
4661
if(tree[k].add)
627475}
76void
interval_add(ll k,ll ll,ll rr,ll val)
7786
if(tree[k].add||tree[k].v) down(k);
87 ll mid=tree[k].r+tree[k].l>>1;88
if(ll<=mid) interval_add(ls,ll,rr,val);
89if(rr>mid) interval_add(rs,ll,rr,val);
90update(k);91}
92void
interval_change(ll k,ll ll,ll rr,ll val)
93102
if(tree[k].add||tree[k].v) down(k);
103 ll mid=tree[k].r+tree[k].l>>1
;104
if(ll<=mid) interval_change(ls,ll,rr,val);
105if(rr>mid) interval_change(rs,ll,rr,val);
106update(k);
107}
108void
interval_sum(ll k,ll ll,ll rr)
109115
if(tree[k].add||tree[k].v) down(k);
116 ll mid=tree[k].r+tree[k].l>>1
;117
if(ll<=mid) interval_sum(ls,ll,rr);
118if(rr>mid) interval_sum(rs,ll,rr);
119}
120void
interval_max(ll k,ll ll,ll rr)
121127
if(tree[k].add||tree[k].v) down(k);
128 ll mid=tree[k].r+tree[k].l>>1
;129
if(ll<=mid) interval_max(ls,ll,rr);
130if(rr>mid) interval_max(rs,ll,rr);
131}
132void
interval_min(ll k,ll ll,ll rr)
133139
if(tree[k].add||tree[k].v) down(k);
140 ll mid=tree[k].r+tree[k].l>>1
;141
if(ll<=mid) interval_min(ls,ll,rr);
142if(rr>mid) interval_min(rs,ll,rr);
143}
144int
main()
145157
else
if(how[0]=='
s'&&how[1]=='
e')//
區間賦值
158162
else
if(how[0]=='
s'&&how[1]=='
u')//
區間求和
163168
else
if(how[0]=='
m'&&how[1]=='
a')//
區間最大值
169174
else
if(how[0]=='
m'&&how[1]=='
i')//
區間最小值
175
180}
181return0;
182 }
4927 線段樹練習5
4927 線段樹練習5 時間限制 1 s 空間限制 128000 kb 題目等級 gold 題解 檢視執行結果 題目描述 description 有n個數和5種操作 add a b c 把區間 a,b 內的所有數都增加c set a b c 把區間 a,b 內的所有數都設為c sum a b 查詢區...
4927 線段樹練習5 多重標記
時間限制 1 s 空間限制 128000 kb 題目等級 gold 題解檢視執行結果 有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 的最...
線段樹練習5(codevs 4927)
題目描述 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 的最小值 輸...