BZOJ4196: [Noi2015]软件包管理器 (好题

来源:互联网 发布:java if else 都执行 编辑:程序博客网 时间:2024/05/22 00:48

好题啊,做到这题想起以前靠线段树维护子树的时候

那时候没见过链操作,搞不清树剖有什么用

这题就结合了子树操作和树链操作,也是把dfs序的in out完整用上了

树剖exp++

#include<bits/stdc++.h>//#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h>#include<algorithm>#include<queue>#include<string.h>#include<iostream>#include<math.h>#include<set>#include<map>#include<vector>#include<iomanip>using namespace std;#define ll long long#define pb push_back#define FOR(a) for(int i=1;i<=a;i++)const int inf=0x3f3f3f3f;const int maxn=1e5+9;  //int arr[maxn]; int n; struct EDGE{    int v;int next;}G[maxn<<2];int head[maxn],tot;void init(){    memset(head,-1,sizeof head);tot=0;}void addedge(int u,int v){    ++tot;G[tot].v=v;G[tot].next=head[u];head[u]=tot;} int top[maxn];int pre[maxn];int dep[maxn];int num[maxn];int p[maxn];    //v的对应位置int out[maxn];  //退出时间戳int fp[maxn];   //访问序列int son[maxn];  //重儿子int pos; void dfs1(int u,int fa,int d){    dep[u]=d;    pre[u]=fa;    num[u]=1;    for(int i=head[u];~i;i=G[i].next){        int v=G[i].v;        if(v==fa)continue;        dfs1(v,u,d+1);        num[u]+=num[v];        if(son[u]==-1||num[v]>num[son[u]])son[u]=v;    }}void getpos(int u,int sp){    top[u]=sp;    p[u]=out[u]=++pos;    fp[p[u]]=u;    if(son[u]==-1)return;    getpos(son[u],sp);    for(int i=head[u];~i;i=G[i].next){        int v=G[i].v;        if(v!=son[u]&&v!=pre[u])getpos(v,v);    }    out[u]=pos;} struct NODE{    int lazy;    int add;    int sum;}ST[maxn<<2]; void pushup(int rt){    ST[rt].sum=ST[rt<<1].sum+ST[rt<<1|1].sum;}void pushdown(int l,int r,int rt){    if(ST[rt].lazy){        int m=l+r>>1;ST[rt<<1].add=ST[rt<<1|1].add=ST[rt].add;        ST[rt<<1].sum=(m-l+1)*ST[rt].add;ST[rt<<1].lazy=1;        ST[rt<<1|1].sum=(r-m)*ST[rt].add;ST[rt<<1|1].lazy=1;        ST[rt].lazy=0;    }}void update(int a,int b,int c,int l,int r,int rt){    if(a<=l&&b>=r){        ST[rt].sum=(r-l+1)*c;        ST[rt].lazy=1;        ST[rt].add=c;return;    }    int m=l+r>>1;pushdown(l,r,rt);    if(a<=m)update(a,b,c,l,m,rt<<1);if(b>m)update(a,b,c,m+1,r,rt<<1|1);    pushup(rt);}int query(int a,int b,int l,int r,int rt){    if(a<=l&&b>=r){return ST[rt].sum;}    int m=l+r>>1;pushdown(l,r,rt);    int ans=0;    if(a<=m)ans+=query(a,b,l,m,rt<<1);if(b>m)ans+=query(a,b,m+1,r,rt<<1|1);    return ans;} void solve(int u,int v){    int ans=0;    while(top[u]!=top[v]){        ans+=(-p[top[u]]+p[u])+1-query(p[top[u]],p[u],1,n,1);        update(p[top[u]],p[u],1,1,n,1);        u=pre[top[u]];    }    ans+=p[u]-p[v]+1-query(p[v],p[u],1,n,1);    update(p[v],p[u],1,1,n,1);//cout<<query(p[0],p[0],1,n,1)<<endl;    printf("%d\n",ans);} char op[15];int main(){    memset(son,-1,sizeof son);    scanf("%d",&n);init();    for(int i=1,x;i<n;i++){        scanf("%d",&x);        addedge(x,i);    }    dfs1(0,-1,0);    getpos(0,0);     int q;scanf("%d",&q);    int x;    while(q--){        scanf("%s%d",op,&x);        if(op[0]=='i')solve(x,0);        else{            printf("%d\n",query(p[x],out[x],1,n,1));            update(p[x],out[x],0,1,n,1);        }    }}


原创粉丝点击