博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LOJ 2130 软件包管理器
阅读量:4948 次
发布时间:2019-06-11

本文共 2651 字,大约阅读时间需要 8 分钟。

熟练剖分

路径到根直接向上跳

#include 
#include
#include
using namespace std;const int MAXN=101111;int N, M;int P;string com;struct Vert{ int Fa, Son, Bro; int Size, Dep; int MainSon, Top; int Dps, Dpr;} V[MAXN];void DFS1(int at){ V[at].Size=1; for(int to=V[at].Son;to>0;to=V[to].Bro){ V[to].Dep=V[at].Dep+1; DFS1(to); V[at].Size+=V[to].Size; if(V[at].MainSon<=0 || V[to].Size>V[V[at].MainSon].Size) V[at].MainSon=to; }}int Dfn[MAXN], DFN;void DFS2(int at, int t){ ++DFN; Dfn[DFN]=at;V[at].Dps=DFN; V[at].Top=t; if(V[at].MainSon>0) DFS2(V[at].MainSon, t); for(int to=V[at].Son;to>0;to=V[to].Bro){ if(to==V[at].MainSon) continue; DFS2(to, to); } V[at].Dpr=DFN;/**/}struct Node{ int l, r; int Sum; int opt;} T[MAXN<<2];int L, R, op;int Sum;void BuildTree(int l, int r, int at){ T[at].l=l;T[at].r=r;T[at].Sum=0;T[at].opt=-1; if(l
>1; BuildTree(l, m, at<<1); BuildTree(m+1, r, (at<<1)|1); }}void opr(int at){ T[at].Sum=op*(T[at].r-T[at].l+1);}void cop(int at){ T[at].opt=op;}void pdw(int at){ if(T[at].opt==-1) return; int top=op;op=T[at].opt; opr(at<<1);cop(at<<1); opr((at<<1)|1);cop((at<<1)|1); op=top;T[at].opt=-1;}void pup(int at){ T[at].Sum=T[at<<1].Sum+T[(at<<1)|1].Sum;}int Ask(int at){ if(T[at].l>=L && T[at].r<=R){ return T[at].Sum; } pdw(at); int m=(T[at].l+T[at].r)>>1; int ret=0; if(L<=m) ret+=Ask(at<<1); if(R>m) ret+=Ask((at<<1)|1); return ret;}void Update(int at){ if(T[at].l>=L && T[at].r<=R){ T[at].Sum=op*(T[at].r-T[at].l+1); T[at].opt=op; return; } pdw(at); int m=(T[at].l+T[at].r)>>1; if(L<=m) Update(at<<1); if(R>m) Update((at<<1)|1); pup(at);}int main(){ ios_base::sync_with_stdio(false); cin >> N; for(int i=2, f;i<=N;++i){ cin >> f;++f; V[i].Fa=f;V[i].Bro=V[f].Son;V[f].Son=i; } V[1].Dep=1; DFS1(1); DFS2(1, 1); assert(DFN==N); BuildTree(1, N, 1); cin >> M; while(M--){ cin >> com >> P;++P; Sum=0; if(com[0]=='i'){ op=1; for(int k=P;k>0;k=V[V[k].Top].Fa){ L=V[V[k].Top].Dps;R=V[k].Dps; Sum+=Ask(1); Update(1); } cout << V[P].Dep-Sum << endl; } else{ op=0; L=V[P].Dps;R=V[P].Dpr; Sum=Ask(1); Update(1); cout << Sum << endl; } } return 0;}

转载于:https://www.cnblogs.com/Pickupwin/p/9094146.html

你可能感兴趣的文章
iOS中的#import和class区别
查看>>
节约内存,请使用标签页管理工具:onetab、better onetab
查看>>
jQuery中的事件与动画
查看>>
页面加载骨架
查看>>
关于android系统不关屏设置
查看>>
SONY VPCS138EC降级安装XP
查看>>
[luogu4201][bzoj1063]设计路线【树形DP】
查看>>
手机抓包-手机劫持域名到指定服务器
查看>>
被放逐的皇后 金建云
查看>>
Javascript 有用参考函数
查看>>
点群的判别(三)
查看>>
gradle
查看>>
GNSS 使用DFT算法 能量损耗仿真
查看>>
常见的控制跳转的宏定义
查看>>
JavaSE| 面向对象的三大特征
查看>>
tensorflow Tensorboard可视化-【老鱼学tensorflow】
查看>>
eigen主页
查看>>
暑假周进度报告1
查看>>
兔子数
查看>>
网页抓取 总结
查看>>