zoukankan      html  css  js  c++  java
  • bzoj4196: [Noi2015]软件包管理器

    树链剖分。

    这道题就写个dfs序,乱搞一下就过了。

    简单型的树剖

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 200000 + 10;
    const int maxm = 400000 + 10;
    int g[maxn],v[maxm],next[maxm],eid;
    int size[maxn],son[maxn],top[maxn],f[maxn];
    int st[maxn],ed[maxn],vid;
    int n,m,x;
    char op[20];
    
    void addedge(int a,int b) {
        v[eid]=b; next[eid]=g[a]; g[a]=eid++;
    }
    
    struct Segtree {
        #define lc(x) ((x)<<1)
        #define rc(x) (((x)<<1)|1)
        
        int sumv[maxm],sam[maxm];
        int l[maxm],r[maxm];
        
        void update(int x) {
            sumv[x]=sumv[lc(x)]+sumv[rc(x)];
        }
        
        void push(int x) {
            if(sam[x]==-1) return;
            sam[lc(x)]=sam[x];
            sumv[lc(x)]=sam[x]*(r[lc(x)]-l[lc(x)]+1);
            sam[rc(x)]=sam[x];
            sumv[rc(x)]=sam[x]*(r[rc(x)]-l[rc(x)]+1);
            sam[x]=-1;
        }
        
        void change(int x,int L,int R,int val) {
            if(R<l[x] || L>r[x]) return;
            if(L<=l[x] && r[x]<=R) {
                sam[x]=val; 
                sumv[x]=(r[x]-l[x]+1)*val; 
                return;
            }
            push(x);
            change(lc(x),L,R,val);
            change(rc(x),L,R,val);    
            update(x);
        }
        
        int query(int x,int L,int R) {
            if(R<l[x] || L>r[x]) return 0;
            if(L<=l[x] && r[x]<=R) return sumv[x];
            push(x);
            return (query(lc(x),L,R)+query(rc(x),L,R));
        }
        
        
        void build(int x,int L,int R) {
            l[x]=L; r[x]=R; sam[x]=-1;
            if(L==R) return;
            int mid=(L+R)>>1;
            build(lc(x),L,mid);
            build(rc(x),mid+1,R);
        }
        
    }seg;
    
    
    void dfs1(int u) {
        size[u]=1;
        for(int i=g[u];~i;i=next[i]) {
            dfs1(v[i]);
            size[u]+=size[v[i]];
            if(size[v[i]]>size[son[u]]) son[u]=v[i];
        }
    }
    
    void dfs2(int u,int r) {
        top[u]=r; st[u]=++vid;
        if(son[u]) dfs2(son[u],r);
        for(int i=g[u];~i;i=next[i]) if(v[i] != son[u]) 
            dfs2(v[i],v[i]); 
        ed[u]=vid;
    }
    
    void solve(int x) {
        int res=0;
        while(x) {
            res+=(st[x]-st[top[x]]+1)-seg.query(1,st[top[x]],st[x]);
            seg.change(1,st[top[x]],st[x],1);
            x=top[x];
            x=f[x];
        }
        printf("%d
    ",res);
    }
    
    
    int main() {
        memset(g,-1,sizeof(g));
        scanf("%d",&n);
        for(int i=2;i<=n;i++) {
            scanf("%d",&f[i]);
            f[i]++;
            addedge(f[i],i);
        }
        seg.build(1,1,n);
        dfs1(1); dfs2(1,1);
        scanf("%d",&m);
        while(m--) {
            scanf("%s%d",op,&x);
            x++;
            if(op[0]=='i') solve(x);
            else {
                printf("%d
    ",seg.query(1,st[x],ed[x]));
                seg.change(1,st[x],ed[x],0);
            }
        }
        return 0;    
    }
  • 相关阅读:
    要想成为前端大神,那些你不得不知晓的web前端命名规范。
    正确开启Mockjs的三种姿势:入门参考(一)
    1024码农节-向自己致敬!
    ES6 常用总结(前端开发js技术进阶提升总结)
    JS快速构建数组方法
    React绑定事件动态化的实现方法
    JQ遇到$(‘.xxx’).attr(‘display’)一直返回undefined
    你所要掌握的最简单基础的React渲染优化
    MyBatis Generator
    Spring boot集成redis初体验
  • 原文地址:https://www.cnblogs.com/invoid/p/5630861.html
Copyright © 2011-2022 走看看