安装操作就是链上统计+更改,卸载操作就是子树统计+更改,没有比树剖更合适的了。
数组开小会莫名WA..qwq#include#include using namespace std;const int MAXN=1000005;int n,m;#define ls (cur<<1)#define rs ((cur<<1)+1)#define mid ((l+r)>>1)int sum[MAXN],lazy[MAXN];void pushup(int cur){sum[cur]=sum[ls]+sum[rs];}void pushdown(int cur,int l,int r){ sum[ls]=(lazy[cur])*(mid-l+1); sum[rs]=(lazy[cur])*(r-mid); lazy[ls]=lazy[rs]=lazy[cur]; lazy[cur]=-1;} void build(int cur,int l,int r){ if(l==r){sum[cur]=0;return;} build(ls,l,mid);build(rs,mid+1,r); lazy[cur]=-1; pushup(cur);}void updata(int L,int R,int cur,int l,int r,int w){ if(L<=l&&r<=R){sum[cur]=w*(r-l+1);lazy[cur]=w;return;} if(lazy[cur]!=-1) pushdown(cur,l,r); if(L<=mid) updata(L,R,ls,l,mid,w); if(mid mx) mx=siz[v],hs[cur]=v; }}int top[MAXN],id[MAXN],cnt;void dfs2(int cur,int tp){ id[cur]=++cnt;top[cur]=tp; if(hs[cur]) dfs2(hs[cur],tp); for(int i=head[cur];i;i=e[i].next){ int v=e[i].to; if(v==fa[cur]||v==hs[cur]) continue; dfs2(v,v); }}int query_link(int x,int y){ int ret=0; while(top[x]!=top[y]){ if(dep[top[x]] dep[y]) swap(x,y); ret+=query0(id[x],id[y],1,1,n); return ret;}void updata_link(int x,int y,int w){ while(top[x]!=top[y]){ if(dep[top[x]] dep[y]) swap(x,y); updata(id[x],id[y],1,1,n,w);}int query_subtree(int x){ return query(id[x],id[x]+siz[x]-1,1,1,n);}void updata_subtree(int x,int w){ updata(id[x],id[x]+siz[x]-1,1,1,n,w);}int main(){ scanf("%d",&n); int x; for(int i=2;i<=n;i++) { scanf("%d",&x); x++; add(i,x);add(x,i); } dfs1(1,0); dfs2(1,1); build(1,1,n); scanf("%d",&m); char s[500]; for(int i=1;i<=m;i++){ scanf("%s%d",s,&x); x++; if(s[0]=='i'){ printf("%d\n",query_link(1,x)); updata_link(1,x,1); }else{ printf("%d\n",query_subtree(x)); updata_subtree(x,0); } } return 0;}