博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj4196 [Noi2015]软件包管理器——树链剖分
阅读量:4553 次
发布时间:2019-06-08

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

题目:

树链剖分。

代码如下:

#include
#include
#include
using namespace std;int const maxn=1e5+5;int n,m,fa[maxn],dfn[maxn],end[maxn],top[maxn],to[maxn],siz[maxn],head[maxn],ct,tim;struct N{ int to,next; N(int t=0,int n=0):to(t),next(n) {}}edge[maxn];struct T{
int sum,siz; bool f[3];}t[maxn<<2];int rd(){ int ret=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return ret;}void dfs(int x){ siz[x]=1; for(int i=head[x],u;i;i=edge[i].next) { dfs(u=edge[i].to); if(siz[u]>siz[to[x]])to[x]=u; siz[x]+=siz[u]; }}void dfs2(int x){ dfn[x]=++tim;//不在dfs if(to[x])top[to[x]]=top[x],dfs2(to[x]); for(int i=head[x],u;i;i=edge[i].next) { if((u=edge[i].to)==to[x])continue; top[u]=u; dfs2(u); } end[x]=tim;}void pushup(int x){ int ls=(x<<1),rs=(x<<1|1); t[x].siz=t[ls].siz+t[rs].siz; t[x].sum=t[ls].sum+t[rs].sum;}void pushdown(int x){ if(!t[x].f[0]&&!t[x].f[1])return; int ls=(x<<1),rs=(x<<1|1); for(int i=0;i<=1;i++) if(t[x].f[i]) { t[x].f[i]=0; t[ls].f[i]=1; t[rs].f[i]=1; t[ls].f[!i]=0; t[rs].f[!i]=0; t[ls].sum=t[ls].siz*i; t[rs].sum=t[rs].siz*i; }}void build(int x,int l,int r){ if(l==r){t[x].siz=1;return;} int mid=((l+r)>>1); build(x<<1,l,mid); build(x<<1|1,mid+1,r); pushup(x);}int query(int x,int l,int r,int L,int R,int val){ if(l>=L&&r<=R) { if(val)return t[x].sum; else return t[x].siz-t[x].sum; } int mid=((l+r)>>1),ret=0; pushdown(x); if(mid>=L)ret+=query(x<<1,l,mid,L,R,val); if(mid
<<1|1,mid+1,r,L,R,val); return ret;}void update(int x,int l,int r,int L,int R,int val){ if(l>=L&&r<=R) { t[x].f[val]=1; t[x].f[!val]=0; t[x].sum=t[x].siz*val; return; } int mid=((l+r)>>1); if(mid>=L)update(x<<1,l,mid,L,R,val); if(mid
<<1|1,mid+1,r,L,R,val); pushup(x);}int ask(int x){ int ret=0; while(x) { int l=dfn[top[x]],r=dfn[x]; ret+=query(1,1,n,l,r,0); update(1,1,n,l,r,1); x=fa[top[x]]; } return ret;}int main(){ n=rd(); for(int i=2;i<=n;i++) { fa[i]=rd()+1; edge[++ct]=N(i,head[fa[i]]);head[fa[i]]=ct; } dfs(1); top[1]=1; dfs2(1); build(1,1,n); m=rd(); char ch[15]; for(int i=1,x;i<=m;i++) { scanf("%s",&ch); x=rd()+1; if(ch[0]=='u') { printf("%d\n",query(1,1,n,dfn[x],end[x],1)); update(1,1,n,dfn[x],end[x],0); } if(ch[0]=='i') { printf("%d\n",ask(x)); } } return 0;}

 

转载于:https://www.cnblogs.com/Zinn/p/9188635.html

你可能感兴趣的文章
堆内存管理
查看>>
PIE保护绕过
查看>>
牛客假日团队赛11 A 级数求和
查看>>
2019百度之星初赛一 1005 Seq HDU - 6672 (打表找规律)
查看>>
[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher D - Cyclic Nacklace HDU - 3746(循环节kmp)...
查看>>
Por Costel and the Match Gym - 100923H(经典种类并查集)
查看>>
Happy 2006 POJ - 2773(欧几里得算法 互素问题)
查看>>
[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher E - Period HDU - 1358(循环节kmp)
查看>>
[kuangbin带你飞]专题十二 基础DP1 F - Piggy-Bank HDU - 1114(完全背包)
查看>>
Trailing Zeroes (I) LightOJ - 1028(唯一分解 因子个数)
查看>>
洛谷题 P3366 【模板】最小生成树
查看>>
Farey Sequence POJ - 2478 (欧拉函数 前缀和)
查看>>
[kuangbin带你飞]专题六 最小生成树 B - Networking
查看>>
[kuangbin带你飞]专题十二 基础DP1 E - Super Jumping! Jumping! Jumping! HDU - 1087(不连续单调递增最长子序列的和)...
查看>>
[kuangbin带你飞]专题四 最短路练习 B( POJ 2253) Frogger(spfa)
查看>>
[kuangbin带你飞]专题六 最小生成树 A - Jungle Roads
查看>>
Codeforces Round #570 (Div. 3)B
查看>>
[kuangbin带你飞]专题五 并查集 B - The Suspects
查看>>
[kuangbin带你飞]专题一 简单搜索 E. Find The Multiple
查看>>
[kuangbin带你飞]专题四 最短路练习 C - Heavy Transportation (spfa)最大权值
查看>>