您的位置:首页 > 其它

【BZOJ 1095】 1095: [ZJOI2007]Hide 捉迷藏 (括号序列+线段树)

2017-01-19 17:06 302 查看

1095:[ZJOI2007]Hide捉迷藏

Description

  捉迷藏Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子。某天,Jiajia、Wind和孩子们决定在家里玩
捉迷藏游戏。他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条走廊的分布使得任意两个屋
子都互相可达。游戏是这样进行的,孩子们负责躲藏,Jiajia负责找,而Wind负责操纵这N个屋子的灯。在起初的
时候,所有的灯都没有被打开。每一次,孩子们只会躲藏在没有开灯的房间中,但是为了增加刺激性,孩子们会要
求打开某个房间的电灯或者关闭某个房间的电灯。为了评估某一次游戏的复杂性,Jiajia希望知道可能的最远的两
个孩子的距离(即最远的两个关灯房间的距离)。我们将以如下形式定义每一种操作:C(hange)i改变第i个房
间的照明状态,若原来打开,则关闭;若原来关闭,则打开。G(ame)开始一次游戏,查询最远的两个关灯房间的
距离。

Input

  第一行包含一个整数N,表示房间的个数,房间将被编号为1,2,3…N的整数。接下来N-1行每行两个整数a,b,
表示房间a与房间b之间有一条走廊相连。接下来一行包含一个整数Q,表示操作次数。接着Q行,每行一个操作,如
上文所示。

Output

  对于每一个操作Game,输出一个非负整数到hide.out,表示最远的两个关灯房间的距离。若只有一个房间是关
着灯的,输出0;若所有房间的灯都开着,输出-1。

SampleInput

8

12

23

34

35

36

67

68

7

G

C1

G

C2

G

C1

G

SampleOutput

4

3

3

4

HINT

对于100%的数据,N≤100000,M≤500000。

Source



【分析】

  此乃神题也。。今天的目标就是AC这题ORZ。。

  跪%%%岛姐:

  首先是括号表示法压压压:

  比如这个图:

  

1#include<cstdio>
2#include<cstdlib>
3#include<cstring>
4#include<iostream>
5#include<algorithm>
6usingnamespacestd;
7#defineMaxn100010
8#defineINF0xfffffff
9
10intmymax(intx,inty){returnx>y?x:y;}
11
12inta[Maxn];
13boolc[Maxn];
14intn;
15
16structnode{intx,y,next;}t[2*Maxn];intlen=0;
17intfirst[Maxn];
18
19voidins(intx,inty)
20{
21t[++len].x=x;t[len].y=y;
22t[len].next=first[x];first[x]=len;
23}
24
25structnnode
26{
27intl,r,lc,rc;
28intl1,r1,l2,r2,dis,c1,c2;
29}tr[2*Maxn];
30
31intla[Maxn],lb[Maxn],dfn[Maxn];
32intna,nb,cnt,tot;
33voiddfs(intx,intf)
34{
35nb++;dfn[x]=++tot;
36la[++cnt]=na;lb[cnt]=nb;
37na=0;nb=0;
38for(inti=first[x];i;i=t[i].next)if(t[i].y!=f)
39{
40inty=t[i].y;
41dfs(y,x);
42}
43na++;
44}
45
46voidupd(intx,inty)
47{
48tr[x].l1=tr[x].l2=tr[x].r1=tr[x].r2=-INF;
49tr[x].dis=-INF;
50tr[x].c1=la[y+1];tr[x].c2=lb[y+1];
51if(c[y+1]==1)tr[x].l1=la[y+1]+lb[y+1],tr[x].l2=lb[y+1]-la[y+1];
52if(c[y]==1)tr[x].r1=la[y+1]+lb[y+1],tr[x].r2=la[y+1]-lb[y+1];
53if(c[y]&&c[y+1])tr[x].dis=tr[x].l1;
54}
55
56voidmerge(intx,inty,intz)
57{
58tr[z].dis=mymax(tr[x].dis,tr[y].dis);
59tr[z].dis=mymax(tr[z].dis,mymax(tr[x].r1+tr[y].l2,tr[x].r2+tr[y].l1));
60
61inta=tr[x].c1,b=tr[x].c2,c=tr[y].c1,d=tr[y].c2;
62
63if(b<c)tr[z].c1=a+c-b,tr[z].c2=d;
64elsetr[z].c1=a,tr[z].c2=b+d-c;
65tr[z].l1=mymax(tr[x].l1,mymax(tr[y].l1-b+a,tr[y].l2+a+b));
66tr[z].l2=mymax(tr[x].l2,tr[y].l2+b-a);
67tr[z].r1=mymax(tr[y].r1,mymax(tr[x].r1+d-c,tr[x].r2+c+d));
68tr[z].r2=mymax(tr[y].r2,tr[x].r2+c-d);
69}
70
71intbuild(intl,intr)
72{
73intx=++tot;
74tr[x].l=l;tr[x].r=r;
75if(l==r)
76{
77upd(x,l);
78}
79else
80{
81intmid=(l+r)>>1;
82tr[x].lc=build(l,mid);
83tr[x].rc=build(mid+1,r);
84merge(tr[x].lc,tr[x].rc,x);
85}
86returnx;
87}
88
89voidchange(intx,inty)
90{
91if(y<1||y>n)return;
92if(tr[x].l==tr[x].r)
93{
94upd(x,tr[x].l);
95return;
96}
97intmid=(tr[x].l+tr[x].r)>>1;
98if(y<=mid)change(tr[x].lc,y);
99elsechange(tr[x].rc,y);
100merge(tr[x].lc,tr[x].rc,x);
101}
102
103chars[110];
104
105intmain()
106{
107intbl;
108scanf("%d",&n);
109for(inti=1;i<=n;i++)c[i]=1;
110bl=n;
111memset(first,0,sizeof(first));len=0;
112for(inti=1;i<n;i++)
113{
114intx,y;
115scanf("%d%d",&x,&y);
116ins(x,y);ins(y,x);
117}
118na=0,nb=0;cnt=0;tot=0;dfs(1,0);
119n--;
120tot=0;build(1,n);
121intq;
122scanf("%d",&q);
123for(inti=1;i<=q;i++)
124{
125scanf("%s",s);
126if(s[0]=='C')
127{
128intx;
129scanf("%d",&x);
130if(c[dfn[x]])bl--;
131elsebl++;
132c[dfn[x]]=c[dfn[x]]?0:1;
133change(1,dfn[x]-1);
134change(1,dfn[x]);
135}
136else
137{
138if(bl==0)printf("-1\n");
139elseif(bl==1)printf("0\n");
140elseprintf("%d\n",tr[1].dis);
141}
142}
143return0;
144}


ViewCode


2017-01-2009:11:16


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
章节导航