[BZOJ 1095] [ZJOI 2007]Hide 捉迷藏

  在BZ上连续MLE n次后,终于A了.

  自己YY的动态点分写法,思路还是很清楚的,但是比较卡内存.

  用到了MAP导致复杂度比其他的代码多了一个log,看来需要去借鉴一下别人怎么写的.

 updata in 2017-05-25:

  发现了一些没必要储存的东西.

  1. 存储当前重心某子树堆的位置的MAP可以利用在重心树上的儿子记录此信息.

  2.求树上距离可以用RMQ,没必要直接拿MAP记下来.

  改完这两个令我颇不舒服的地方,复杂度就正常多了.

  1 /*
  2 动态树分治
  3 BZOJ1095
  4 全局路径查询
  5 单点修改,全局查询
  6 */
  7 #include<cstdio>
  8 #include<iostream>
  9 #include<cstdlib>
 10 #include<cstring>
 11 #include<ctime>
 12 #include<cmath>
 13 #include<vector>
 14 #include<map>
 15 #include<set>
 16 #include<bitset>
 17 #include<algorithm>
 18 #include<iomanip>
 19 #include<queue>
 20 #include<stack>
 21 using namespace std;
 22 #define ll long long
 23 #define up(i,j,n) for(int i=j;i<=n;++i)
 24 #define db double
 25 #define piii pair< pair<int,int>,int>
 26 #define pb push_back
 27 #define FILE "dealing"
 28 #define eps 1e-8
 29 template<class T> inline bool cmin(T&a,T b){return a>b?a=b,true:false;}
 30 template<class T> inline bool cmax(T&a,T b){return a<b?a=b,true:false;}
 31 template<class T> inline T squ(T a){return a*a;}
 32 const int maxn=100000+10,base=23,limit=3e8,inf=2000000;
 33 int read(){
 34     int x=0,f=1,ch=getchar();
 35     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 36     while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
 37     return x*f;
 38 }
 39 int n,Q;
 40 vector<int>E[maxn];
 41 struct dui{
 42     priority_queue<int> q,q2;
 43     void pop(){
 44         while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
 45         if(!q.empty())q.pop();
 46     }
 47     int top(){
 48         while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
 49         if(!q.empty())return q.top();
 50         else return -1;
 51     }
 52     void erase(int x){
 53         q2.push(x);
 54         while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
 55     }
 56     void push(int x){
 57         q.push(x);
 58         while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
 59     }
 60     int getans(){
 61         int s1=top();pop();
 62         int s2=top();push(s1);
 63         if(s1==-1)return -1;
 64         if(s2==-1)return -2;
 65         return s1+s2;
 66     }
 67 }All,DA[maxn],MA[maxn<<1];int cnt=0;
 68 int siz[maxn],vis[maxn],Mx[maxn],dep[maxn];
 69 int getsize(int x,int fa){
 70     siz[x]=1;
 71     for(int i=0;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
 72         getsize(E[x][i],x);
 73         siz[x]+=siz[E[x][i]];
 74     }
 75 }
 76 void getroot(int x,int fa,int& rt,int S){
 77     Mx[x]=0;
 78     for(int i=0;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
 79         getroot(E[x][i],x,rt,S);
 80         cmax(Mx[x],siz[E[x][i]]);
 81     }
 82     cmax(Mx[x],S-siz[x]);
 83     if(Mx[x]<Mx[rt])rt=x;
 84 }
 85 int fa[maxn];
 86 vector<int> F[maxn];
 87 map<int,int>A[maxn],B[maxn];
 88 void DFS(int x,int fa,int Cnt,int FA){
 89     A[FA][x]=Cnt;
 90     B[FA][x]=dep[x];
 91     MA[Cnt].push(dep[x]);
 92     for(int i=0;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
 93         dep[E[x][i]]=dep[x]+1;
 94         DFS(E[x][i],x,Cnt,FA);
 95     }
 96 }
 97 int work(int x,int S){
 98     int rt=0;
 99     getroot(x,0,rt,siz[x]);
100     vis[rt]=1;
101     getsize(rt,0);x=rt;
102     cnt++;F[x].push_back(cnt);MA[cnt].push(0);
103     A[x][x]=cnt;B[x][x]=0;
104     for(int i=0;i<E[x].size();i++)if(!vis[E[x][i]]){
105         cnt++;
106         F[x].push_back(cnt);
107         dep[E[x][i]]=1;
108         DFS(E[x][i],0,cnt,x);
109     }
110     for(int i=0;i<F[x].size();i++)
111         DA[x].push(MA[F[x][i]].top());
112     int val=DA[x].getans();
113     if(val!=-1&&val!=-2)All.push(val);
114     for(int i=0;i<E[x].size();i++)if(!vis[E[x][i]]){
115         int y=work(E[x][i],siz[E[x][i]]);
116         fa[y]=x;
117     }
118     return x;
119 }
120 char s[10];
121 int f[maxn],sum;
122 void motify(int x,int FA){
123     while(x){
124         int val=DA[x].getans();
125         if(val!=-1&&val!=-2)All.erase(val);
126         
127         int id=A[x][FA];
128         val=MA[id].top();if(val!=-1)DA[x].erase(val);
129         if(!f[FA])MA[id].push(B[x][FA]);
130         else MA[id].erase(B[x][FA]);
131         val=MA[id].top();if(val!=-1)DA[x].push(val);
132         
133         val=DA[x].getans();
134         if(val!=-1&&val!=-2)All.push(val);
135         x=fa[x];
136     }
137 }
138 int main(){
139     freopen(FILE".in","r",stdin);
140     freopen(FILE".out","w",stdout);
141     n=read();Mx[0]=inf;sum=n;
142     up(i,2,n){
143         int x=read(),y=read();
144         E[x].push_back(y);
145         E[y].push_back(x);
146     }
147     getsize(1,0);
148     work(1,siz[1]);
149     Q=read();
150     while(Q--){
151         scanf("%s",s+1);
152         if(s[1]=='G'){
153             if(sum==0)printf("-1
");
154             else if(sum==1)printf("0
");
155             else printf("%d
",All.top());
156         }
157         if(s[1]=='C'){
158             int x=read();
159             f[x]^=1;
160             if(!f[x])sum++;
161             else sum--;
162             motify(x,x);
163         }
164     }
165     return 0;
166 }
View Code

 

原文地址:https://www.cnblogs.com/chadinblog/p/6901946.html