zkw線段樹 標記下放

2021-06-16 07:36:53 字數 4861 閱讀 8785

zkw線段樹的標記上傳好像只能做區間修改的rmq,但標記下放應用面就與樸素線段樹差不多了,但是漂亮很多。

在進行修改或詢問時,我們先將當前區間的標記全部下放,從左右開區間端點從頂向下跑一邊下放就是,同時,對於修改後,再從左右區間把祖先更新,zkw的非遞迴性質發揮的淋漓盡致。其實很好編,下面兩道題都是1a、

好吧,我又重溫了zkw的部落格,這種方法不太純正,但是,暫時還不理解那種標記永久化,所以還是先用這種方法。

rqnoj 中國結

題意:子樹取反,子樹詢問1的個數。

轉成括號序列線段樹維護,線段樹記1的數目,取反標記域。

跑得不是很快,主要是rqnoj上pascal每個點最快速度都要比c慢幾十ms

var sum,t:array[1..524288]of longint;

n,m,ans,m1,ss,len,high:longint;

l,r,tail:array[1..200000]of longint;

next,sora:array[1..500000]of longint;

procedure inf;

begin

assign(input,'chinese.in');reset(input);

assign(output,'chinese.out');rewrite(output)

end;

procedure ouf;

begin

close(input);close(output)

end;

procedure pushdown(x:longint);

var p,i,ne:longint;

begin

p:=m1;

for i:=high downto 1 do begin

p:=p>>1;

if t[x>>i]<>0 then begin

ne:=x>>i;

sum[ne<<1]:=p-sum[ne<<1]; t[ne<<1]:=t[ne<<1] xor 1;

sum[ne<<1+1]:=p-sum[ne<<1+1];t[ne<<1+1]:=t[ne<<1+1] xor 1;

t[ne]:=0

endend

end;

procedure updata(x:longint);

begin

while x<>0 do begin

sum[x]:=sum[x<<1]+sum[x<<1+1];

x:=x>>1

endend;

procedure modify(l,r:longint);

var ll,rr,p:longint;

begin

l:=l+m1-1;r:=r+m1+1;

ll:=l>>1;rr:=r>>1;

p:=1;

pushdown(l);pushdown(r);

while not(l xor r=1) do begin

if l and 1=0 then begin sum[l+1]:=p-sum[l+1];t[l+1]:=t[l+1] xor 1 end;

if r and 1=1 then begin sum[r-1]:=p-sum[r-1];t[r-1]:=t[r-1] xor 1 end;

l:=l>>1;r:=r>>1;p:=p<<1

end;

updata(ll);updata(rr)

end;

function ask(l,r:longint ): longint;

begin

l:=l+m1-1;r:=r+m1+1;ask:=0;

pushdown(l);pushdown(r);

while not(l xor r=1) do begin

if l and 1=0 then ask:=ask+sum[l+1];

if r and 1=1 then ask:=ask+sum[r-1];

l:=l>>1;r:=r>>1

endend;

procedure origin;

var i:longint;

begin

m1:=1;high:=0; //high

while m1<=n<<1+2 do begin

m1:=m1<<1;inc(high)

end;

for i:=1 to n do tail[i]:=i;ss:=n

end;

procedure link(x,y:longint);

begin

inc(ss);next[tail[x]]:=ss;tail[x]:=ss;sora[ss]:=y;

inc(ss);next[tail[y]]:=ss;tail[y]:=ss;sora[ss]:=x

end;

procedure dfs(x,y:longint);

var i,ne:longint;

begin

inc(len);l[x]:=len;

i:=x;

while next[i]<>0 do begin

i:=next[i];ne:=sora[i];

if ne<>y then dfs(ne,x)

end;

inc(len);r[x]:=len

end;

procedure init;

var i,x,y:longint;

ch:char;

begin

readln(n);

origin;

for i:=1 to n-1 do begin

readln(x,y);

link(x,y)

end;

len:=0;

dfs(1,0);

readln(m);

for i:=1 to m do begin

readln(ch,x);

if ch='c' then begin

modify(l[x],r[x])

endelse begin

ans:=ask(l[x],r[x]);

writeln(ans>>1)

endend;

end;

begin

inf;

init;

oufend.

poj 2777

題意:區間染色,統計區間顏色數目。

練手題,速度是pascal第一,總排名第一版,空間也不錯。

var c,t:array[1..262144]of longint;

ans,n,p,o,high,m1:longint;

procedure pushdown(x:longint);

var i,ne:longint;

begin

for i:=high downto 1 do

if t[x>>i]<>0 then begin

ne:=x>>i;

c[ne<<1]:=t[ne];c[ne<<1+1]:=t[ne];

t[ne<<1]:=t[ne];t[ne<<1+1]:=t[ne];

t[ne]:=0

endend;

procedure updata(x:longint);

begin

while x<>0 do begin

c[x]:=c[x<<1] or c[x<<1+1];

x:=x>>1

end;

end;

procedure modify(l,r,color:longint);

var ll,rr,e:longint;

begin

if l>r then begin

e:=l;l:=r;r:=e

end;

l:=l+m1-1;r:=r+m1+1;color:=1<<(color-1);

ll:=l>>1;rr:=r>>1;

pushdown(l);pushdown(r);

while not(l xor r=1) do begin

if l and 1=0 then begin

c[l+1]:=color;

t[l+1]:=c[l+1]

end;

if r and 1=1 then begin

c[r-1]:=color;

t[r-1]:=c[r-1]

end;

l:=l>>1;r:=r>>1

end;

updata(ll);updata(rr)

end;

function ask(l,r:longint ): longint;

var e,k:longint;

begin

if l>r then begin

e:=l;l:=r;r:=e

end;

l:=l+m1-1;r:=r+m1+1;

ask:=0;

pushdown(l);pushdown(r);

while not(l xor r=1) do begin

if l and 1=0 then ask:=ask or c[l+1];

if r and 1=1 then ask:=ask or c[r-1];

l:=l>>1;r:=r>>1

end;

k:=0;

while ask<>0 do begin

k:=k+ask and 1;

ask:=ask>>1

end;

exit(k)

end;

procedure origin;

begin

m1:=1;high:=0;

while m1

線段樹和zkw線段樹

好啦,我們就開始說說線段樹吧 線段樹是個支援區間操作和查詢的東東,平時的話還是蠻實用的 下面以最基本的區間加以及查詢區間和為例 線段樹顧名思義就是棵樹嘛,葉子節點是每個基本點,它們所對應的父親就是它們的和,具體如下圖 但是對於這樣的線段樹來說,操作所需的時間是遠達不到我們的要求的 會被t 因為我們會...

zkw線段樹小結

zkw zkwzk w線段樹作為迴圈式線段樹具有較小的常數.其實樹狀陣列本質上就是線段樹 下標為 1,n 1,n 1,n 預處理乙個2 k n2 k n 2k n.然後總空間為2k 12 2k 1 2 k 1 4n 2 4n 2k 1 4n 後面令k 2 kk 2 k k 2k 那麼乙個葉子x xx...

鏈結 zkw線段樹

資料結構 走近zkw線段樹 一 資料結構 走近zkw線段樹 二 線段樹的擴充套件之 zkw線段樹 include define lc x x 1 define rc x x 1 1 using namespace std const int maxn 100005 int max int a,int...