codeforces 877E Danil and a Part-time Job
阿新 • • 發佈:2018-10-04
namespace += names query struct ttr int mat %d
目錄
- codeforces 877E Danil and a Part-time Job
- 題意:
- 題解:
- Code:
codeforces 877E Danil and a Part-time Job
題目傳送門
題意:
給出一個樹,每一個點都有權值,權值為0或1,要求支持兩個操作:子樹權值翻轉,子樹權值和。
題解:
比較水的一道E題吧,反正就是用線段樹維護\(Dfn\)序就行了,差不多樹剖那個套路吧。。
Code:
#include<bits/stdc++.h> using namespace std; const int N=2e5+500; int idx[N],x[N],v[N],sz[N],heav[N]; int n,cnt,q; vector<int>G[N]; namespace SegmentTree { struct node { int l,r,sz,cnt,flip; }t[N<<3]; #define ls(o) (o)<<1 #define rs(o) (o)<<1|1 void Update(int o) { t[o].cnt=t[ls(o)].cnt+t[rs(o)].cnt; } void Pushdown(int o) { if(!t[o].flip) return ; t[ls(o)].cnt=t[ls(o)].sz-t[ls(o)].cnt; t[rs(o)].cnt=t[rs(o)].sz-t[rs(o)].cnt; t[ls(o)].flip^=1; t[rs(o)].flip^=1; t[o].flip^=1; return ; } void Build(int o,int l,int r) { t[o].l=l;t[o].r=r;t[o].sz=r-l+1; if(l==r) { t[o].cnt=v[l]; return ; } int mid=(l+r)>>1; Build(ls(o),l,mid); Build(rs(o),mid+1,r); Update(o); return ; } void Modify(int o,int l,int r) { if(t[o].l>=l&&t[o].r<=r) { t[o].cnt=t[o].sz-t[o].cnt; t[o].flip^=1; return ; } Pushdown(o); int mid=(t[o].l+t[o].r)>>1; if(mid>=l) Modify(ls(o),l,r); if(mid<r) Modify(rs(o),l,r); Update(o); return ; } int Query(int o,int l,int r) { if(t[o].l>=l&&t[o].r<=r) return t[o].cnt; Pushdown(o); int mid=(t[o].l+t[o].r)>>1; int ans=0; if(mid>=l) ans+=Query(ls(o),l,r); if(mid<r) ans+=Query(rs(o),l,r); return ans; } } using namespace SegmentTree; namespace Solver { void Dfs1(int o,int fa) { sz[o]=1; int Mxson=-1; for(int i=0;i<(int)G[o].size();i++) { int to=G[o][i]; if(to==fa) continue; Dfs1(to,o); sz[o]+=sz[to]; if(sz[to]>Mxson) { Mxson=sz[to]; heav[o]=to; } } } void Dfs2(int o) { idx[o]=++cnt; v[cnt]=x[o]; if(!heav[o]) return ; Dfs2(heav[o]); for(int i=0;i<(int)G[o].size();i++) { int to=G[o][i]; if(idx[to]) continue; Dfs2(to); } } void Init() { Dfs1(1,1); Dfs2(1); Build(1,1,n); } void Change(int o) {Modify(1,idx[o],idx[o]+sz[o]-1);} int Ask(int o) {return Query(1,idx[o],idx[o]+sz[o]-1);} } int main() { scanf("%d",&n); for(int i=2,p;i<=n;i++) { scanf("%d",&p); G[p].push_back(i); G[i].push_back(p); } for(int i=1;i<=n;i++) scanf("%d",&x[i]); Solver::Init(); scanf("%d",&q); while(q--) { char s[10]; int x; scanf("%s%d",s,&x); if(s[0]=='g') printf("%d\n",Solver::Ask(x)); else Solver::Change(x); } return 0; }
codeforces 877E Danil and a Part-time Job