SHOI2015 腦洞治療儀

2022-03-27 06:22:16 字數 2148 閱讀 7219

我太sb啦

合併的時候又漏了,又漏了,又漏了

我個sb

這是個板子題,並不知道為什麼shoi2015會考這麼板子的題,但是我又sb了,又sb了,又sb了,又沒有1a

顯然我是涼了

這道題有三個操作

區間清零

將乙個區間清零,之後補到另乙個區間去,但是有可能補不滿

詢問乙個區間內最大全零子串

顯然這都是線段樹的板子操作,對於維護這種區間最長的連續的子串,我們只需要多維護兩個陣列\(rc[i],lc[i]\),分別表示乙個區間內從左開始和從右開始的最長子串,於是就可以合併啦

之後第二個操作看起來很唬人,但是其實也非常板子,我們要找最長的區間,這個區間內的0的個數必須小於等於那個清零了的區間裡原來的1的個數

這顯然是滿足單調性的,我們顯然可以將這個區間二分出來

於是這裡需要二分一下,同時二分的過程中線段樹查詢一下乙個區間內1的個數來判斷,所以操作2的複雜度是\(o(log^2n)\)了

看起來\(o(mlog^2n)\)加上線段樹的大常數跑\(200000\)有些危險,但是人要有信仰

之後最sb的是我寫錯的地方,就是\(pushup\)還有\(query\)合併區間的時候,如果乙個區間的左半部分全是0,那麼這個區間的從左開始的最長的全0子串肯定可以延伸到右端去,所以這裡不能簡單地\(lc[i]=lc[i<<1]\)了,我們需要判斷一下在合併

可見我有多麼sb

**

#include#include#include#define re register

#define maxn 200005

#define max(a,b) ((a)>(b)?(a):(b))

struct treenode

;int l[maxn<<2],r[maxn<<2],tag[maxn<<2];

int d[maxn<<2],ans[maxn<<2],lc[maxn<<2],rc[maxn<<2];

int n,m;

inline int read()

inline void pushup(int i)

void build(int x,int y,int i)

int mid=l[i]+r[i]>>1;

build(x,mid,i<<1);

build(mid+1,y,i<<1|1);

pushup(i);

}inline void pushdown(int i)

if(!tag[i]) }

void change(int x,int y,int v,int i)

pushdown(i);

int mid=l[i]+r[i]>>1;

if(y<=mid) change(x,y,v,i<<1);

else if(x>mid) change(x,y,v,i<<1|1);

else change(x,y,v,i<<1),change(x,y,v,i<<1|1);

pushup(i);

}int ask(int x,int y,int i)

treenode query(int x,int y,int i)

; pushdown(i);

int mid=l[i]+r[i]>>1;

if(y<=mid) return query(x,y,i<<1);

if(x>mid) return query(x,y,i<<1|1);

treenode lson=query(x,y,i<<1),rson=query(x,y,i<<1|1);

int len=max(max(lson.len,rson.len),lson.rr+rson.ll);

int ll,rr;

if(lson.ll==mid-l[i]+1) ll=lson.ll+rson.ll;

else ll=lson.ll;

if(rson.rr==r[i]-mid) rr=rson.rr+lson.rr;

else rr=rson.rr;

return (treenode);

}int main()

change(xx,xx+ty-1,1,1);

} if(opt==2) printf("%d\n",query(x,y,1).len);

} return 0;

}

SHOI2015 腦洞治療儀

嘟嘟嘟 這題其實就是乙個線段樹維護最大連續和的水題。別的操作不說,操作1只要二分找區間前 k 個0即可。需要注意的是,因為操作1兩區間可能有交,因此要先清空再二分查詢 複雜度 o n log 2 n include include include include include include in...

SHOI2015 腦洞治療儀

洛谷題目鏈結 珂朵莉樹吼啊!對於操作 0 其實就是區間賦值為 0 的操作,直接套模板就行了 對於操作 1 應該是這個題目最難的操作了 雖然還是很簡單 我們先查詢 l 0,r 0 這個區間的 1 的數量,最後掃一遍 l 1,r 1 這個區間,如果 1 的數量夠的話直接更改區間值,如果不夠的話就把其中夠...

SHOI2015 腦洞治療儀 題解 (線段樹)

題目鏈結 題目大意 給定乙個只含 0 和 1 的序列。有三種操作 1.把 l,r 內所有數改為 0 2.把 l,r 內所有 1 拿走來填 l r 內所有 0 多了丟掉,少了優先從左開始填 3.查詢 l,r 內最長的 0 串。一眼能看出來考最大子段和。但是 好難調啊qaq 對於一段序列,我們要維護 4...