题目大意:
一棵树,开始所有点权值为0 支持两种操作:
① 将它到根路径上所有点(包括自己与根)的权值都变为1 求点权被改变的点的个数
② 将它的子树内所有点以及自己的权值变为1 求点权被改变的点的个数
思路:
看懂了题之后就很裸了
然后我因为pushdown的tag向下传递少打了右子树的“|1”调了好久
orz
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 101010 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int nxt[MAXN<<1],fst[MAXN],n,to[MAXN<<1],Cnt; 21 int cnt[MAXN],bl[MAXN],fa[MAXN],dep[MAXN],hsh[MAXN]; 22 struct data {int l,r,tag,sum;}tr[MAXN<<2]; 23 void add(int u,int v) {nxt[++Cnt]=fst[u],fst[u]=Cnt,to[Cnt]=v;} 24 void dfs(int x) 25 { 26 cnt[x]=1; 27 for(int i=fst[x];i;i=nxt[i]) 28 { 29 if(to[i]==fa[x]) continue; 30 fa[to[i]]=x,dep[to[i]]=dep[x]+1; 31 dfs(to[i]); 32 cnt[x]+=cnt[to[i]]; 33 } 34 } 35 void Dfs(int x,int anc) 36 { 37 int hvs=0;hsh[x]=++Cnt,bl[x]=anc; 38 for(int i=fst[x];i;i=nxt[i]) 39 if(to[i]!=fa[x]&&cnt[to[i]]>cnt[hvs]) hvs=to[i]; 40 if(!hvs) return ; 41 Dfs(hvs,anc); 42 for(int i=fst[x];i;i=nxt[i]) 43 if(to[i]!=fa[x]&&to[i]!=hvs) Dfs(to[i],to[i]); 44 } 45 void build(int k,int l,int r) 46 { 47 tr[k].l=l,tr[k].r=r,tr[k].sum=tr[k].tag=0; 48 if(l==r) return ; 49 int mid=(l+r)>>1; 50 build(k<<1,l,mid); 51 build(k<<1|1,mid+1,r); 52 } 53 void pushdown(int k) 54 { 55 tr[k<<1].tag=tr[k<<1|1].tag=tr[k].tag; 56 if(tr[k].tag==1) tr[k<<1].sum=tr[k<<1].r-tr[k<<1].l+1,tr[k<<1|1].sum=tr[k<<1|1].r-tr[k<<1|1].l+1; 57 if(tr[k].tag==-1) tr[k<<1].sum=tr[k<<1|1].sum=0; 58 tr[k].tag=0; 59 } 60 void upd(int k,int a,int b,int x) 61 { 62 int l=tr[k].l,r=tr[k].r; 63 if(a==l&&b==r) {if(x==1) tr[k].sum=r-l+1,tr[k].tag=1;else tr[k].sum=0,tr[k].tag=-1;return ;} 64 if(tr[k].tag) pushdown(k); 65 int mid=(l+r)>>1; 66 if(mid>=b) upd(k<<1,a,b,x); 67 else if(mid<a) upd(k<<1|1,a,b,x); 68 else {upd(k<<1,a,mid,x);upd(k<<1|1,mid+1,b,x);} 69 tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum; 70 } 71 int query(int k,int a,int b) 72 { 73 int l=tr[k].l,r=tr[k].r; 74 if(a==l&&b==r) return tr[k].sum; 75 int mid=(l+r)>>1; 76 if(tr[k].tag) pushdown(k); 77 if(mid>=b) return query(k<<1,a,b); 78 else if(mid<a) return query(k<<1|1,a,b); 79 else return query(k<<1,a,mid)+query(k<<1|1,mid+1,b); 80 } 81 int main() 82 { 83 n=read(); 84 for(int i=2;i<=n;i++) {fa[i]=read()+1;add(i,fa[i]);add(fa[i],i);} 85 dep[1]=1; 86 dfs(1);Cnt=0; 87 Dfs(1,1); 88 build(1,1,n); 89 int T=read();char ch[18]; 90 int a,res; 91 while(T--) 92 { 93 scanf("%s",ch);a=read()+1,res=0; 94 if(ch[0]=='i') 95 { 96 while(a!=0) 97 { 98 res+=(hsh[a]-hsh[bl[a]]+1-query(1,hsh[bl[a]],hsh[a])); 99 upd(1,hsh[bl[a]],hsh[a],1); 100 a=fa[bl[a]]; 101 } 102 } 103 else 104 { 105 res+=query(1,hsh[a],hsh[a]+cnt[a]-1); 106 upd(1,hsh[a],hsh[a]+cnt[a]-1,-1); 107 } 108 printf("%d ",res); 109 } 110 }