一颗树,N个点,初始标记均为0,两个操作:
①查询某个点到根的路径上0的个数,并全部变为1
②查询某个点子树里1的个数,并全部变成0
emm我不知道说什么。
①=链查询+链覆盖,②=子树查询+子树覆盖
直接上代码吧。只是为了发篇博客2333
(我觉得等我写了树链剖分的详解之后该把这个删了。。这种模板没什么好解析的)
#include
#define rint register int
#define endll '\n'
#define ivoid inline void
#define iint inline int
#define ll long long
using namespace std;
const int N=1e6+5;
const int M=3e3+5;
const int inf=0x3f3f3f3f;
int n,m,a,b,k,x,y,s,t,u,v,w,l,r,ql,qr,q;
int deep[N],top[N],id[N],rank[N],son[N],size[N],head[N],fa[N],col[N];
int cnt=1,sum,ans,pos1,pos2,pos3,change,rt;
char c[8],c1;
struct Edge{int v,next;}edge[N<<1];
struct Node{int val,tag;}node[N<<4];
iint rad()
{
int x=0,f=1;char c;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x*f;
}
ivoid addedge(int u,int v){edge[++cnt].v=v,edge[cnt].next=head[u],head[u]=cnt;}
ivoid dfs1(int now)
{
size[now]=1;
for(rint i=head[now];i;i=edge[i].next){
int d=edge[i].v;
if(d==fa[now])continue;
fa[d]=now,deep[d]=deep[now]+1,dfs1(d);
if(size[d]>size[son[now]])son[now]=d;
size[now]+=size[d];
}
}
ivoid dfs2(int now,int op)
{
id[now]=++cnt;rank[cnt]=now;top[now]=op;
if(!son[now])return;dfs2(son[now],op);
for(rint i=head[now];i;i=edge[i].next){
int d=edge[i].v;
if(d==fa[now]||d==son[now])continue;
dfs2(d,d);
}
}
ivoid pushup(int n)
{
int lson=n<<1,rson=(n<<1)|1;
node[n].val=node[lson].val+node[rson].val;
}
ivoid pushdown(int l,int r,int n)
{
if(node[n].tag==0)return;
int lson=n<<1,rson=(n<<1)|1,mid=(l+r)>>1;
if(node[n].tag==1){
node[lson].val=mid-l+1;node[rson].val=r-mid;
node[lson].tag=1,node[rson].tag=1;
}
if(node[n].tag==-1){
node[lson].val=node[rson].val=0;
node[lson].tag=node[rson].tag=-1;
}
node[n].tag=0;
}
ivoid build(int l,int r,int n)
{
if(l==r){return;}
int mid=(l+r)>>1;
build(l,mid,n<<1);build(mid+1,r,(n<<1)|1);
pushup(n);
}
ivoid changesome(int l,int r,int n,int ql,int qr)
{
if(l>=ql&&r<=qr){
node[n].val=(r-l+1);
node[n].tag=1;
return;
}
pushdown(l,r,n);
int mid=(l+r)>>1;
if(mid>=ql)changesome(l,mid,n<<1,ql,qr);
if(mid<qr)changesome(mid+1,r,(n<<1)|1,ql,qr);
pushup(n);
}
ivoid crashsome(int l,int r,int n,int ql,int qr)
{
if(l>=ql&&r<=qr){
node[n].val=0;
node[n].tag=-1;
return;
}
pushdown(l,r,n);
int mid=(l+r)>>1;
if(mid>=ql)crashsome(l,mid,n<<1,ql,qr);
if(mid<qr)crashsome(mid+1,r,(n<<1)|1,ql,qr);
pushup(n);
}
ivoid query(int l,int r,int n,int ql,int qr)
{
if(l>=ql&&r<=qr){
ans+=(r-l+1)-node[n].val;
return;
}
pushdown(l,r,n);
int mid=(l+r)>>1;
if(mid>=ql)query(l,mid,n<<1,ql,qr);
if(mid<qr)query(mid+1,r,(n<<1)|1,ql,qr);
pushup(n);
}
ivoid Lca_query(int x,int y)
{
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
ql=id[top[x]],qr=id[x],query(1,n,1,ql,qr);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
ql=id[x],qr=id[y],query(1,n,1,ql,qr);
}
ivoid Lca_change(int x,int y)
{
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
ql=id[top[x]],qr=id[x],changesome(1,n,1,ql,qr);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
ql=id[x],qr=id[y],changesome(1,n,1,ql,qr);
}
int main()
{
n=rad();
for(rint i=1;i<n;i++)v=rad(),addedge(i+1,v+1),addedge(v+1,i+1);
cnt=0;dfs1(1),dfs2(1,1),build(1,n,1);rt=1;
m=rad();
for(rint i=1;i<=m;i++){
cin>>c,x=rad();ans=0;x++;
if(c[0]=='i')Lca_query(x,rt),cout<<ans<<endll,Lca_change(x,rt);
if(c[0]=='u')ql=id[x],qr=id[x]+size[x]-1,query(1,n,1,ql,qr),
cout<<qr-ql+1-ans<<endll,crashsome(1,n,1,ql,qr);
}
}