NOI 2015 软件包管理器 题解&代码
来源:互联网 发布:淘宝卖什么最好 编辑:程序博客网 时间:2024/06/14 20:01
简单的树链剖分= =不过第一次写真正意义上的树剖坑了我整整五个小时…写出来的代码也不算模板级别的思路,模板还得再找几道题习惯习惯再整理
**对了= =才没有抄过模板呢…在下的模板都是自己根据写法和记忆的难易自己整理出来的
**调了两天,题目已经忘了,等我去整理一下
给出了一颗以0为根节点的Bool类型树,对于一个节点x有两个操作:
1、将该节点到根节点的路径上所有节点值都修改为1
2、将以该节点为根的子树上的节点全部修改为0
对于每次操作,输出这次被修改的节点个数
**需要特别注意的是线段树节点的空间要开四倍…还有要把dfs序号和节点本身的编号分清= =嗯,还有没想好不要乱写
**0号节点开头总归是不好算的,我把编号全部加一了,新的编号下所有节点有一个不存在的父亲0节点
#include<iostream>#include<vector>#include<stdio.h>#define lson (o<<1)#define rson ((o<<1)|1)using namespace std;const int maxn=100005;int n,q,fa[maxn],x,ans,tot;int tree[maxn*4],lazy[maxn*4],pa[maxn],son[maxn],rt[maxn],size[maxn];int in[maxn],out[maxn],deep[maxn];vector <int> edge[maxn];char s[10];int dfs(int r,int d){ deep[r]=d; size[r]=1; int z=-1; for(int i=0;i<edge[r].size();i++) { size[r]+=dfs(edge[r][i],d+1); if(z==-1 || size[edge[r][i]]>size[z])z=edge[r][i]; } son[r]=z; return size[r];}void buildtree(int c,int root){ in[c]=++tot; rt[c]=root; if(!edge[c].size()) { out[c]=tot; return; } buildtree(son[c],root); for(int i=0;i<edge[c].size();i++) if(edge[c][i]!=son[c]) buildtree(edge[c][i],edge[c][i]); out[c]=tot;}void pushdown(int o,int l,int r){ if(lazy[o]) { tree[o]=(r-l+1)*(lazy[o]-1); if(l!=r) { int mid=(l+r)/2; tree[lson]=(mid-l+1)*(lazy[o]-1); tree[rson]=(r-mid)*(lazy[o]-1); lazy[lson]=lazy[rson]=lazy[o]; } } lazy[o]=0;}void maintain(int o,int l,int r){ if(l!=r)tree[o]=tree[lson]+tree[rson];}void addtree(int o,int l,int r,int L,int R,int c){ pushdown(o,l,r); if(l>R || r<L)return; if(l>=L && r<=R) { lazy[o]=c+1; tree[o]=(r-l+1)*(lazy[o]-1); return; } int mid=(l+r)/2; addtree(lson,l,mid,L,R,c); addtree(rson,mid+1,r,L,R,c); maintain(o,l,r);}void ins(int o,int c){ bool flag=true; ans=tree[1]; if(c) { while(o) { addtree(1,1,tot,in[rt[o]],in[o],c); o=fa[rt[o]]; } ans=tree[1]-ans; } else { addtree(1,1,tot,in[o],out[o],c); ans-=tree[1]; }}int main(void){ scanf("%d",&n); for(int i=2;i<=n;i++) { scanf("%d",&fa[i]); fa[i]++; edge[fa[i]].push_back(i); } dfs(1,1); buildtree(1,1); scanf("%d",&q); for(int i=1;i<=q;i++) { scanf("%s",s); scanf("%d",&x); x++; ans=0; if(s[0]=='u') { ins(x,0); printf("%d\n",ans); } else { ins(x,1); printf("%d\n",ans); } } return 0;}
0 0
- NOI 2015 软件包管理器 题解&代码
- NOI 2015 day1 t2 软件包管理器 题解&代码(c++)
- NOI 2015 软件包管理器
- 【NOI 2015 软件包管理器】【树剖】
- bzoj-4196 NOI-2015 软件包管理器
- NOI 2015 DAY1 T2 软件包管理器 树链剖分
- 【树链剖分】【NOI 2015】【bzoj 4196】软件包管理器
- NOI 2015 day1 T2 软件包管理器
- NOI 2015 d1t2 洛谷 【P2146】 软件包管理器
- NKOJ 3423 (NOI 2015) 软件包管理器 (树链剖分+线段树)
- [题解][NOI2015]软件包管理器
- NOI2015 软件包管理器 题解
- 【树链剖分】[BZOJ 4196][NOI 2014]软件包管理器
- NOI 2015 荷马史诗 题解&代码
- 软件包管理器
- 【NOI 2014】【BZOJ 3670】动物园 题解&代码(C++)
- NOI 2002 题解
- NOI 2003 题解
- android中OptionMenu和ContextMenu创建
- Android-内功篇-理解 Android Build 系统
- 创造更好的浏览体验-HTML5 history API
- HDU 5593 ZYB's Tree
- 使用Kompex事务功能
- NOI 2015 软件包管理器 题解&代码
- Java8中新增加的集合类
- 动态规划:从新手到专家
- Loadrunner服务器问题解决之--mdrv.eve进程未中止导致服务器磁盘空间占满
- 自己项目中做的UI布局
- poj 3080
- Linux如何实现开机启动程序详解
- StringBuffer的用法
- Android安卓万能适配器adpter和viewholder