其实也算是个板子吧,思想还是很好的
一开始真的没什么思路,然后想了想要是这个软件已经装上了就设成1,不然设成0,
查询的话直接做点到根节点的权值和就好了,要是卸载了,就查询这个点为为根节点的权值和,然后用子树大小减去上面的权值和就好了
区间覆盖的话将lazytag改动一下就好了
放上丑丑的代码
#include<bits/stdc++.h> #define ls(x) x<<1 #define rs(x) x<<1|1 using namespace std; const int N=4e5+6; int m,n,k,p,l,cnt,tot,res,root; int lg[N],sum[N],son[N],fa[N],dep[N],top[N],head[N],size[N],id[N]; struct edge { int nx,to; } e[N]; void add_edge(int a,int b) { cnt++;e[cnt].to=b;e[cnt].nx=head[a];head[a]=cnt; cnt++;e[cnt].to=a;e[cnt].nx=head[b];head[b]=cnt; } void push_up(int p) { sum[p]=sum[ls(p)]+sum[rs(p)]; } void build(int p,int l,int r) { lg[p]=-1; if (l==r) { sum[p]=1; return; } int mid=(l+r)>>1; build(ls(p),l,mid); build(rs(p),mid+1,r); push_up(p); } void push_down(int p,int lenn) { if (lg[p]==-1) return; lg[ls(p)]=lg[p]; lg[rs(p)]=lg[p]; sum[ls(p)]=lg[p]*(lenn-(lenn>>1)); sum[rs(p)]=lg[p]*(lenn>>1); lg[p]=-1; } void update(int p,int l,int r,int nl,int nr,int k) { if (nl<=l&&r<=nr) { sum[p]=(r-l+1)*k; lg[p]=k; return; } push_down(p,(r-l+1)); int mid=(l+r)>>1; if (nl<=mid) update(ls(p),l,mid,nl,nr,k); if (nr>mid) update(rs(p),mid+1,r,nl,nr,k); push_up(p); } void query(int p,int l,int r,int xl,int xr) { if (xl<=l&&r<=xr) { res+=sum[p]; return; } push_down(p,(r-l+1)); int mid=(l+r)>>1; if (xl<=mid) query(ls(p),l,mid,xl,xr); if (xr>mid) query(rs(p),mid+1,r,xl,xr); } void dfs1(int x,int f,int deep) { dep[x]=deep; fa[x]=f; size[x]=1; int maxson=-1; for (int i=head[x];i;i=e[i].nx) { int y=e[i].to; if (y==fa[x]) continue; dfs1(y,x,deep+1); size[x]+=size[y]; if (size[y]>maxson) {son[x]=y;maxson=size[y];} } } void dfs2(int x,int topf) { id[x]=++tot; top[x]=topf; if (!son[x]) return; dfs2(son[x],topf); for (int i=head[x];i;i=e[i].nx) { int y=e[i].to; if (y==fa[x]||y==son[x]) continue; dfs2(y,y); } } int queson(int x) { int ans=0; res=0; query(1,1,n,id[x],id[x]+size[x]-1); ans=res; return ans; } int querange(int x,int y) { int ans=0; while (top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); res=0; query(1,1,n,id[top[x]],id[x]); ans+=res; x=fa[top[x]]; } if (dep[x]>dep[y]) swap(x,y); res=0; query(1,1,n,id[x],id[y]); ans+=res; return ans; } void uprange(int x,int y,int k) { while (top[x]!=top[y]) { if (dep[top[x]]<dep[top[y]]) swap(x,y); update(1,1,n,id[top[x]],id[x],k); x=fa[top[x]]; } if (dep[x]>dep[y]) swap(x,y); update(1,1,n,id[x],id[y],k); } int main() { scanf("%d",&n); root=1; for (int i=1;i<=n-1;i++) { int x; scanf("%d",&x); x++; add_edge(x,i+1); } dfs1(root,0,1); dfs2(root,root); build(1,1,n); scanf("%d",&m); string s;int x; for (int i=1;i<=m;i++) { cin>>s; scanf("%d",&x); x++; if (s=="install") {printf("%d\n",querange(x,root));uprange(x,root,0);} if (s=="uninstall") {printf("%d\n",size[x]-queson(x));update(1,1,n,id[x],id[x]+size[x]-1,1);} } return 0; }
原文:https://www.cnblogs.com/Hale522520/p/10623528.html