本文主要是介绍洛谷 P2146 软件包管理器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接
题目分析:
很裸的树链剖分,没啥可讲的,不过我也不晓得我的怎么就错了,调试了半天,输出了样例,最后只过了两个点,打的我好崩溃!需要学习树剖的可以点击树链剖分详解
程序代码
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn=200005;
int n,k=0,x,head[maxn],q,deep[maxn],father[maxn],size[maxn];
int tid[maxn],top[maxn],son[maxn],tidnum=0,pos[maxn];
char s[15];
struct node {int to,next;
} edge[maxn<<1];
struct Node {int left,right,flag,sum;
} tree[maxn<<2];
void add(int u,int v) {edge[++k].to=v;edge[k].next=head[u];head[u]=k;
}
int read() {int x=0;char ch=getchar();while(ch<48||ch>57) ch=getchar();while(ch>=48&&ch<=57) x=x*10+ch-48,ch=getchar();return x;
}
void dfs1(int x,int fa,int depth) {size[x]=1;father[x]=fa;deep[x]=depth;for(int i=head[x]; i; i=edge[i].next) {if(edge[i].to==fa) continue;dfs1(edge[i].to,x,depth+1);size[x]+=size[edge[i].to];if(!son[x]||size[edge[i].to]>size[son[x]]) son[x]=edge[i].to;}
}
void dfs2(int x,int tp) {tid[x]=++tidnum;pos[tid[x]]=x;top[x]=tp;if(!son[x]) return;dfs2(son[x],tp);for(int i=head[x]; i; i=edge[i].next) {if(edge[i].to!=son[x]&&edge[i].to!=father[x])dfs2(edge[i].to,edge[i].to);}
}
void build(int id,int l,int r) {tree[id].left=l;tree[id].right=r;tree[id].sum=0;tree[id].flag=-1;if(l==r) return;int mid=(l+r)>>1;build(id<<1,l,mid);build(id<<1|1,mid+1,r);return;
}
void downdata(int id) {tree[id<<1].sum=(tree[id<<1].right-tree[id<<1].left+1)*tree[id].flag;tree[id<<1|1].sum=(tree[id<<1|1].right-tree[id<<1|1].left+1)*tree[id].flag;tree[id<<1].flag=tree[id<<1|1].flag=tree[id].flag;tree[id].flag=-1;
}
int get(int id,int l,int r) {if(tree[id].right<l||tree[id].left>r) return 0;if(tree[id].right<=r&&tree[id].left>=l) return tree[id].sum;if(tree[id].flag!=-1) downdata(id);return get(id<<1,l,r)+get(id<<1|1,l,r);
}
void update(int id,int l,int r,int val) {if(tree[id].right<l||tree[id].left>r) return;if(tree[id].right<=r&&tree[id].left>=l) {tree[id].sum=(tree[id].right-tree[id].left+1)*val;tree[id].flag=val;return;}if(tree[id].flag!=-1) downdata(id);update(id<<1,l,r,val);update(id<<1|1,l,r,val);tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;return;
}
void change(int u,int v,int val) {while(top[u]!=top[v]) {if(deep[top[u]]<deep[top[v]]) std::swap(u,v);update(1,tid[top[u]],tid[u],val);u=father[top[u]];}if(deep[u]>deep[v]) std::swap(u,v);update(1,tid[u],tid[v],val);return;
}
int main() {n=read();for(int i=2; i<=n; i++) {x=read();x++;add(x,i);}dfs1(1,1,1);dfs2(1,1);q=read();build(1,1,tidnum);for(int i=1; i<=q; i++) {scanf("%s",s);x=read();x++;int t1=tree[1].sum;if(s[0]=='i') {change(1,x,1);int t2=tree[1].sum;printf("%d\n",abs(t2-t1));}if(s[0]=='u') {update(1,tid[x],tid[x]+size[x]-1,0);int t2=tree[1].sum;printf("%d\n",abs(t1-t2));}}return 0;
}
这篇关于洛谷 P2146 软件包管理器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!