讨论 / 只过四个点,后面普通保护错误,求助!!
464271301 2013-03-02 17:48:00
点我顶贴 收藏 删除
程序如下,是用线段树做的。

var n,m,tt,tot,ans:longint;

h,next,head,sta,en:array[1..200000] of longint;

sum:array[1..300000] of longint;

v:array[1..100000] of boolean;

ch:char;

procedure bfs(x:longint);

var now:longint;

begin

inc(tt);

sta[x]:=tt;

now:=head[x];

v[x]:=true;

while now<>0 do

begin

if not v[h[now]] then

bfs(h[now]);

now:=next[now];

end;

en[x]:=tt;

end;

procedure init;

var i,a,b:longint;

begin

readln(n);

tot:=0;

for i:=1 to n-1 do

begin

readln(a,b);

inc(tot);

h[tot]:=b;

next[tot]:=head[a];

head[a]:=tot;

inc(tot);

h[tot]:=a;

next[tot]:=head[b];

head[b]:=tot;

end;

fillchar(sum,sizeof(sum),0);

fillchar(v,sizeof(v),#0);

tt:=0;

bfs(1);

end;

procedure change(k,a,b,l,r:longint);

var mid,lc,lb:longint;

begin

if a=b then

begin

sum[k]:=1-sum[k];

exit;

end;

mid:=(a+b)>>1;

lc:=k<<1;

lb:=k<<1+1;

if v[k] then

begin

v[lc]:=not(v[lc]);

v[lb]:=not(v[lb]);

sum[lc]:=mid-a+1-sum[lc];

sum[lb]:=b-mid-sum[lb];

v[k]:=not(v[k]);

end;

if (l<=a) and (b<=r) then

begin sum[k]:=(b-a+1-sum[k]);

v[k]:=not(v[k]);exit;end;

if l<=mid then change(lc,a,mid,l,r);

if mid<r then change(lb,mid+1,b,l,r);

sum[k]:=sum[lc]+sum[lb];

end;

procedure find(k,a,b,l,r:longint);

var mid,lc,lb:longint;

begin

if (l<=a) and (b<=r) then

begin

inc(ans,sum[k]);

exit;

end;

mid:=(a+b)>>1;

lc:=k<<1;

lb:=k<<1+1;

if v[k] then

begin

v[lc]:=not(v[lc]);

v[lb]:=not(v[lb]);

sum[lc]:=mid-a+1-sum[lc];

sum[lb]:=b-mid-sum[lb];

v[k]:=not(v[k]);

end;

if l<=mid then find(lc,a,mid,l,r);

if mid<r then find(lb,mid+1,b,l,r);

end;

procedure work;

var a:longint;

begin

readln(m);

fillchar(v,sizeof(V),#0);

while m>0 do

begin

dec(m);

read(ch);

case ch of

'C':begin

readln(a);

change(1,1,n,sta[a],en[a]);

end;

'Q':begin

readln(a);

ans:=0;

find(1,1,n,sta[a],en[a]);

writeln(ans);

end;

end;

end;

end;

begin

init;

work;

end.

#1 jiangzh@2013-03-02 17:48:00
回复 删除
我和你一样 不过最后六个点是超时。。。。。
查看更多回复
提交回复