标签:dfs 软件 build add sizeof lse const swa turn
原来NOI也有这样的题啊,而且还和当年HAOI2015上午T2可以说是撞车了,当年HA的省队这道题应该都A了。
// q.c
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define lc o<<1
#define rc o<<1^1
using namespace std;
const int M=100000+10;
/**************************************************************************************/
struct Edge {
int u,v,nex; Edge() {}
Edge(int a,int b,int c):u(a),v(b),nex(c) {}
}ed[M<<1];
int head[M],cnt;
void add_edge(int a,int b) {
ed[cnt]=Edge(a,b,head[a]); head[a]=cnt++;
ed[cnt]=Edge(b,a,head[b]); head[b]=cnt++;
}
/**************************************************************************************/
int f[M],dep[M],size[M],son[M];
void dfs1(int u,int fa,int d) {
f[u]=fa,size[u]=1,dep[u]=d;
int i; Edge e;
for(i=head[u];~i;i=ed[i].nex) {
e=ed[i];
if(!f[e.v]) {
dfs1(e.v,u,d+1); size[u]+=size[e.v];
if(size[e.v]>size[son[u]]||!son[u]) son[u]=e.v;
}
}
}
int top[M],id[M],nd[M],dck,LEFT[M];
void dfs2(int u,int TP) {
top[u]=TP; LEFT[u]=id[u]=++dck; nd[dck]=u;
if(!son[u]) return ; dfs2(son[u],TP);
int i; Edge e; LEFT[u]=max(LEFT[u],LEFT[son[u]]);
for(i=head[u];~i;i=ed[i].nex) {
e=ed[i];
if(e.v!=f[u]&&e.v!=son[u]) {
dfs2(e.v,e.v);
LEFT[u]=max(LEFT[u],LEFT[e.v]);
}
}
}
/**************************************************************************************/
int L[M<<2],R[M<<2],ins[M<<2],uns[M<<2],tag[M<<2];
void build(int o,int l,int r) {
L[o]=l,R[o]=r,uns[o]=r-l+1;
if(l==r) return ;
int mid=(l+r)>>1;
build(lc,l,mid); build(rc,mid+1,r);
}
void DOWN(int o) {
if(tag[o]==1) {
ins[lc]=R[lc]-L[lc]+1,uns[lc]=0,tag[lc]=1;
ins[rc]=R[rc]-L[rc]+1,uns[rc]=0,tag[rc]=1;
} else {
ins[lc]=0,uns[lc]=R[lc]-L[lc]+1,tag[lc]=2;
ins[rc]=0,uns[rc]=R[rc]-L[rc]+1,tag[rc]=2;
}
tag[o]=0;
}
void UP(int o) {
ins[o]=ins[lc]+ins[rc]; uns[o]=uns[lc]+uns[rc];
}
int add(int o,int l,int r) {
if(l<=L[o]&&R[o]<=r) {
int tmp=uns[o];
ins[o]=R[o]-L[o]+1,uns[o]=0,tag[o]=1;
return tmp;
} else {
if(tag[o]) DOWN(o);
int mid=(L[o]+R[o])>>1,ans=0;
if(l<=mid) ans+=add(lc,l,r);
if(r>mid) ans+=add(rc,l,r); UP(o);
return ans;
}
}
int sub(int o,int l,int r) {
if(l<=L[o]&&R[o]<=r) {
int tmp=ins[o];
ins[o]=0,uns[o]=R[o]-L[o]+1,tag[o]=2;
return tmp;
} else {
if(tag[o]) DOWN(o);
int mid=(L[o]+R[o])>>1,ans=0;
if(l<=mid) ans+=sub(lc,l,r);
if(r>mid) ans+=sub(rc,l,r); UP(o);
return ans;
}
}
/**************************************************************************************/
int install(int a,int b) {
int ans=0;
while(top[a]!=top[b]) {
if(dep[top[a]]<dep[top[b]]) swap(a,b);
ans+=add(1,id[top[a]],id[a]);
a=f[top[a]];
}
if(dep[a]>dep[b]) swap(a,b);
return ans+add(1,id[a],id[b]);
}
int unstall(int a) {
int ans=0;
ans=sub(1,id[a],LEFT[a]);
return ans;
}
/**************************************************************************************/
int main() {
freopen("manager.in","r",stdin);
freopen("manager.out","w",stdout);
int n,q,a; char str[17];
scanf("%d",&n);
memset(head,-1,sizeof(head));
for(int i=1;i<n;i++) {
scanf("%d",&a);
add_edge(i+1,a+1);
}
dfs1(1,-1,0); dfs2(1,1); build(1,1,dck);
scanf("%d",&q);
for(int i=1;i<=q;i++) {
scanf("%s%d",str,&a); ++a;
if(str[0]==‘i‘) printf("%d\n",install(1,a));
else printf("%d\n",unstall(a));
}
return 0;
}
标签:dfs 软件 build add sizeof lse const swa turn
原文地址:https://www.cnblogs.com/qjs12/p/8892675.html