BZOJ 1095: [ZJOI2007]Hide 捉迷藏 动态树分治
2017-09-18 00:38
447 查看
1095: [ZJOI2007]Hide 捉迷藏
Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 4043 Solved: 1702
[Submit][Status][Discuss]
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。Sample Input
81 2
2 3
3 4
3 5
3 6
6 7
6 8
7
G
C 1
G
C 2
G
C 1
G
Sample Output
43
3
4
HINT
对于100%的数据, N ≤100000, M ≤500000。非常棒的题
#include<cmath> #include<ctime> #include<cstdio> #include<cstring> #include<cstdlib> #include<complex> #include<iostream> #include<algorithm> #include<iomanip> #include<vector> #include<string> #include<bitset> #include<queue> #include<map> #include<set> using namespace std; typedef long long ll; inline int read() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x; } void print(int x) {if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');} const int N=100100,inf=0X3f3f3f3f; struct Que { priority_queue<int> A,B; void push(int x){if(x!=-inf)A.push(x);} void pop(int x){if(x!=-inf)B.push(x);} int top() { while(!B.empty()&&A.top()==B.top())A.pop(),B.pop(); return !A.empty()?A.top():-inf; } int two() { if(A.size()-B.size()<2)return -inf; int x=top();A.pop(); int y=top();A.push(x); return x+y; } }q1 ,q2 ,q; vector<int>vec ; int ecnt,last ; struct EDGE{int to,nt;}e[N<<1]; inline void add(int u,int v) {e[++ecnt]=(EDGE){v,last[u]};last[u]=ecnt;} int n,sum,off; int root,size ,f ; bool vis ,black ; void getroot(int u,int fa) { size[u]=1;f[u]=0; for(int i=last[u];i;i=e[i].nt) if(e[i].to^fa&&!vis[e[i].to]) { getroot(e[i].to,u);size[u]+=size[e[i].to]; f[u]=max(size[e[i].to],f[u]); } f[u]=max(f[u],sum-size[u]); if(f[u]<f[root])root=u; } // source destination void seek(int u,int fa,int d,int dest) { q2[dest].push(d); vec[u].push_back(d); for(int i=last[u];i;i=e[i].nt) if(!vis[e[i].to]&&e[i].to^fa) seek(e[i].to,u,d+1,dest); } int fa ; void init(int u,int ffa) { fa[u]=ffa;vis[u]=1; q1[u].push(0); for(int i=last[u];i;i=e[i].nt) if(!vis[e[i].to]) { sum=size[e[i].to];root=0;getroot(e[i].to,u); seek(e[i].to,u,1,root); q1[u].push(q2[root].top()); init(root,u); } q.push(q1[u].two()); } void setrev(int u) { register int tmp1,tmp2,tmp3,tmp4,v,i; tmp1=q1[u].two(); black[u]?q1[u].pop(0):q1[u].push(0); tmp2=q1[u].two(); if(tmp1^tmp2)q.pop(tmp1),q.push(tmp2); for(v=u,i=vec[u].size()-1;fa[v];v=fa[v],i--) { tmp1=q2[v].top(); black[u]?q2[v].pop(vec[u][i]):q2[v].push(vec[u][i]); tmp2=q2[v].top(); if(tmp1==tmp2)continue; tmp3=q1[fa[v]].two(); q1[fa[v]].pop(tmp1);q1[fa[v]].push(tmp2); tmp4=q1[fa[v]].two(); if(tmp3^tmp4)q.pop(tmp3),q.push(tmp4); } } int main() { n=off=sum=read(); register int i,u,v; for(i=1;i<n;++i){u=read();v=read();add(u,v),add(v,u);} for(i=1;i<=n;++i)black[i]=1; f[0]=inf;getroot(1,0);init(root,0); int Q=read();char opt[2]; while(Q--) { scanf("%s",opt); if(opt[0]=='C') { u=read();setrev(u); off+=black[u]?-1:1;black[u]^=1; } else { if(!off){puts("-1");} else if(off==1){puts("0");} else print(q.top()),puts(""); } } return 0; } /* 8 1 2 2 3 3 4 3 5 3 6 6 7 6 8 7 G C 1 G C 2 G C 1 G 4 3 3 4 */
相关文章推荐
- BZOJ1095: [ZJOI2007]Hide 捉迷藏
- 【BZOJ1095】[ZJOI2007]Hide 捉迷藏【动态树分治】
- 动态点分治:Bzoj1095: [ZJOI2007]Hide 捉迷藏
- [BZOJ1095][ZJOI2007][线段树]Hide捉迷藏
- bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏
- 动态点分治:Bzoj1095: [ZJOI2007]Hide 捉迷藏
- 【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏
- BZOJ 1095【ZJOI2007】Hide捉迷藏
- bzoj1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树/动态点分治+堆)
- 【BZOJ1095】[ZJOI2007]Hide 捉迷藏 动态树分治+堆
- [BZOJ]1095 Hide捉迷藏(ZJOI2007)
- bzoj1095 [ZJOI2007]Hide 捉迷藏
- bzoj1095 [ZJOI2007]Hide 捉迷藏(动态点分治+堆)
- [bzoj1095][ZJOI2007]Hide 捉迷藏——线段树+括号序列
- bzoj 1095: [ZJOI2007]Hide 捉迷藏 (动态点分治)
- BZOJ 1095: [ZJOI2007]Hide 捉迷藏(线段树维护括号序列)
- bzoj1095: [ZJOI2007]Hide 捉迷藏
- spoj2666 Qtree4(类似于bzoj1095: [ZJOI2007]Hide 捉迷藏)详解
- BZOJ1095: [ZJOI2007]Hide 捉迷藏