傳送門
不得不說 這真是一道不錯的線段樹的題目
這一道題的大意就是說
一開始所有的狀態均為0
會有m次指令
每一次可以把乙個點的狀態進行更改
原來是0就變成1
原來是1就變成0
為了鍛鍊**能力 我決定還是中規中矩地寫線段樹
這一道題還規定了一種串 就是0和1間隔交替 (比如010101 101 01010)
你每一次更改之後 要求出所有的點組成的序列中最長的連續「01」串
那麼這一道題如果用線段樹來做 轉移會稍微複雜一點
我們定義sum為當前區間最長的01串
lsum為當前區間最長的字首01串
rsum為當前區間最長的字尾01串
那我們怎麼進行轉移呢
先說sum
sum可以是左區間的sum、右區間sum的最大值
也可以是左區間的右半部分(字尾)和右區間的左半部分(字首) 這兩個01串拼起來
當然 這也有一定的條件 必須左半部分的最後乙個字元與右半區間的第乙個字元是不相同的 拼接起來之後才合法
然後lsum怎麼轉移?
首先肯定可以是左半區間的lsum轉移過來
但是還有一種情況
就是如果左半區間整個都是合法的01串(也就是左半區間的字首長度 就等於 整個左半區間的長度)
那麼和起來之後最長的字首01串有可能是整個左半區間+右半區間的字首串
同樣 這也有一定的條件 就是必須左半區間的最後乙個字元等於右半區間的第乙個字元
rsum則與lsum同理
有可能是右半區間的rsum轉移過來
也有可能是整個右半區間+左半區間的字尾
條件與lsum的類似
這樣子我們就非常完美地建出了一棵線段樹
這樣子我們的解法其實更加高階
題目可以隨便詢問任何乙個區間 我都可以非常自信地回答出該區間內合法的01串的長度
接下來就上我的巨集偉**啦
(其實我也非常驚訝為什麼我10分鐘就做出來了。。一遍ac。。)
//敲之甚急 **凌亂 請見諒p2253 好乙個一中腰鼓!
#include#define maxn 20005
using
namespace
std;
intcolor[maxn];
struct
nodet[maxn
<<2
];void build(int p,int l,int
r)
int mid=l+r>>1
; build(p*2
,l,mid);
build(p*2+1,mid+1
,r);
t[p].sum=max(t[p*2].sum,t[p*2+1
].sum);
if(color[t[p*2].r]!=color[t[p*2+1].l]) t[p].sum=max(t[p].sum,t[p*2].rsum+t[p*2+1
].lsum);
t[p].lsum=t[p*2
].lsum;
if(t[p*2].lsum==(t[p*2].r-t[p*2].l+1)&&color[t[p*2].r]!=color[t[p*2+1
].l])
t[p].lsum=max(t[p].lsum,t[p*2].r-t[p*2].l+1+t[p*2+1
].lsum);
t[p].rsum=t[p*2+1
].rsum;
if(t[p*2+1].rsum==(t[p*2+1].r-t[p*2+1].l+1)&&color[t[p*2].r]!=color[t[p*2+1
].l])
t[p].rsum=max(t[p].rsum,t[p*2+1].r-t[p*2+1].l+1+t[p*2
].rsum);
return;}
void change(int p,int l,int r,int
ind)
int mid=l+r>>1
;
if(ind>mid)
change(p*2+1,mid+1
,r,ind);
else change(p*2
,l,mid,ind);
t[p].sum=max(t[p*2].sum,t[p*2+1
].sum);
if(color[t[p*2].r]!=color[t[p*2+1].l]) t[p].sum=max(t[p].sum,t[p*2].rsum+t[p*2+1
].lsum);
t[p].lsum=t[p*2
].lsum;
if(t[p*2].lsum==(t[p*2].r-t[p*2].l+1)&&color[t[p*2].r]!=color[t[p*2+1
].l])
t[p].lsum=max(t[p].lsum,t[p*2].r-t[p*2].l+1+t[p*2+1
].lsum);
t[p].rsum=t[p*2+1
].rsum;
if(t[p*2+1].rsum==(t[p*2+1].r-t[p*2+1].l+1)&&color[t[p*2].r]!=color[t[p*2+1
].l])
t[p].rsum=max(t[p].rsum,t[p*2+1].r-t[p*2+1].l+1+t[p*2
].rsum);
}void
ask()
intmain()
return0;
}
P2253 好乙個一中腰鼓!
話說我大一中的運動會就要來了,據本班同學劇透 其實早就知道了 我萌萌的初二年將要表演腰鼓 噴 這個無厘頭的題目便由此而來。ivan亂入 忽一人大呼 好乙個安塞腰鼓!滿座寂然,無敢譁者,遂與外人間隔。設想一下,腰鼓有兩面,一面是紅色的,一面是白色的。初二的蘇大學神想給你這個oier出一道題。假設一共有...
P2253 好乙個一中腰鼓!
題意 給你乙個序列,初始是0,每次乙個操作,把乙個數 1 每次求出最長01串的長度 正解 線段樹 雖然暴力能過 對於每個區間,記錄三個值 lmax,以l為首的01串長度 rmax,以r為尾的01串長度 mmax,既不以l又不以r為為端點的完全包在區間內的最長01串長度 注意合併!include in...
P2253 好乙個一中腰鼓!
話說我大一中的運動會就要來了,據本班同學劇透 其實早就知道了 我萌萌的初二年將要表演腰鼓 噴 這個無厘頭的題目便由此而來。ivan亂入 忽一人大呼 好乙個安塞腰鼓!滿座寂然,無敢譁者,遂與外人間隔。設想一下,腰鼓有兩面,一面是紅色的,一面是白色的。初二的蘇大學神想給你這個oier出一道題。假設一共有...