【bzoj4196】[NOI2015]软件包管理器
2017-03-02 21:17
489 查看
树剖
完全没有对链的操作,维护一个dfs序就好
这个题调了1个多小时,树链剖分写丑了。。。
要注意树剖的线段树维护的是dfs序,所以起止是1 - n而不是0 - n-1
其实也是因为从来把1当作根结点,所以偶尔把0当作根结点就容易写丑了,平常的练习还是要培养自己的码风,这样有助于比赛的时候正常的发挥.
完全没有对链的操作,维护一个dfs序就好
这个题调了1个多小时,树链剖分写丑了。。。
要注意树剖的线段树维护的是dfs序,所以起止是1 - n而不是0 - n-1
其实也是因为从来把1当作根结点,所以偶尔把0当作根结点就容易写丑了,平常的练习还是要培养自己的码风,这样有助于比赛的时候正常的发挥.
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> //树剖的线段树维护的是dfs序,所以起止是1 - n而不是0 - n-1 using namespace std; const int N=100010; int n,m,sz,qx,te; char s[15]; int head ,num ,son ,fa ,tp ,size ; struct edge{ int u,v,next; }e[200020]; struct seg{ int l,r; int numi,numu,tag; }tr[600010]; inline int F() { register int aa,bb;register char ch; while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');ch=='-'?aa=bb=0:(aa=ch-'0',bb=1); while(ch=getchar(),ch>='0'&&ch<='9')aa=(aa<<3)+(aa<<1)+ch-'0';return bb?aa:-aa; } void add(int u,int v) { e[++te].u=u; e[te].v=v; e[te].next=head[u]; head[u]=te; } void dfs1(int x) { size[x]=1; int maxson=0; for (int i=head[x];i;i=e[i].next) { int v=e[i].v; if (v==fa[x])continue; fa[v]=x; dfs1(v); size[x]+=size[v]; if (size[v]>maxson)son[x]=v,maxson=size[v]; } } void dfs2(int x,int chain) { tp[x]=chain; num[x]=++sz; if(son[x]==-1)return; dfs2(son[x],chain); for (int i=head[x];i;i=e[i].next) { int v=e[i].v; if (v==fa[x]||v==son[x])continue; dfs2(v,v); } } void pushdown(int k) { int l=tr[k].l,r=tr[k].r; if (tr[k].tag==-1||l==r)return; int mid=(l+r)>>1; tr[k<<1].tag=tr[k<<1|1].tag=tr[k].tag; if (tr[k].tag==0) { tr[k<<1].numu=mid-l+1; tr[k<<1|1].numu=r-mid; tr[k<<1].numi=tr[k<<1|1].numi=0; } else { tr[k<<1].numi=mid-l+1; tr[k<<1|1].numi=r-mid; tr[k<<1].numu=tr[k<<1|1].numu=0; } tr[k].tag=-1; } void updata(int k) { tr[k].numi=tr[k<<1].numi+tr[k<<1|1].numi; tr[k].numu=tr[k<<1].numu+tr[k<<1|1].numu; } void build(int k,int l,int r) { tr[k].l=l,tr[k].r=r,tr[k].tag=-1; if (l==r) { tr[k].numi=0; tr[k].numu=1; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); updata(k); } void change(int k,int x,int y,int z) { // cout<<tr[k].l<<' '<<tr[k].r<<' '<<tr[k].numi<<' '<<tr[k].numu<<' '<<x<<' '<<y<<endl; int l=tr[k].l,r=tr[k].r; if (x<=l&&r<=y) { tr[k].tag=z; if (z) { qx+=tr[k].numu; tr[k].numi=r-l+1; tr[k].numu=0; } else { qx+=tr[k].numi; tr[k].numu=r-l+1; tr[k].numi=0; } return; } pushdown(k); int mid=(l+r)>>1; if (x<=mid)change(k<<1,x,y,z); if (y>mid)change(k<<1|1,x,y,z); updata(k); } void query(int x) { while(tp[x]!=0) { change(1,num[tp[x]],num[x],1); x=fa[tp[x]]; } change(1,num[tp[x]],num[x],1); return ; } int main() { // freopen("std.in","r",stdin); memset(son,-1,sizeof(son)); int x,u,v; n=F(); for (int i=1;i<n;++i) v=F(),add(v,i); fa[0]=0; dfs1(0);dfs2(0,0);build(1,1,n); m=F(); for (int i=1;i<=m;++i) { // cout<<endl<<endl<<endl<<endl<<endl; scanf("%s",s); x=F();qx=0; if (s[0]=='i')query(x); else change(1,num[x],num[x]+size[x]-1,0); printf("%d\n",qx); } return 0; }
相关文章推荐
- 【bzoj4196】[Noi2015]软件包管理器 树链剖分
- bzoj4196 [Noi2015]软件包管理器
- 【bzoj4196】[Noi2015]软件包管理器
- 【bzoj4196】 [Noi2015]软件包管理器
- BZOJ 4196 [Noi2015]软件包管理器
- [BZOJ4196][NOI2015]软件包管理器 做题笔记
- 【BZOJ4196】【NOI2015】软件包管理器
- [BZOJ4196][Noi2015]软件包管理器
- bzoj 4196: [Noi2015]软件包管理器
- |BZOJ 4196|树链剖分|线段树|[Noi2015]软件包管理器
- BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]
- BZOJ4196: [Noi2015]软件包管理器
- bzoj 4196: [Noi2015]软件包管理器
- BZOJ[4196][Noi2015]洛谷[2146]软件包管理器
- BZOJ 4196([Noi2015]软件包管理器-树链剖分)
- [BZOJ 4196][Noi2015]软件包管理器
- bzoj4196 [Noi2015]软件包管理器 树链剖分
- [bzoj4196] [Noi2015]软件包管理器 (树链剖分)
- BZOJ 4196: [Noi2015]软件包管理器
- 【BZOJ 4196】[Noi2015]软件包管理器