zoukankan      html  css  js  c++  java
  • USACO10FEB]慢下来Slowing down dfs序 线段树

    [USACO10FEB]慢下来Slowing down

    题面 洛谷P2982

    本来想写树剖来着

    暴力数据结构直接模拟,每头牛回到自己的农场后,其子树下的所有牛回到农舍时,必定会经过此牛舍,即:每头牛回舍后,会对其子树所有点造成多一次慢下来的机会。所以先使用(dfs)序将子树操作转化为线性区间操作,之后使用线段树区间修改当前子树全部加一,单点查询当前点覆盖次数。

    注意:

    • (dfs)序上,节点(x)的子树为区间( ext{[dfn[x], dfn[x]+sz[x]-1]}),其中子树大小( ext{sz[x]})包含(x)本身

    AC Code:

    #include <cstdio>
    #define MAXN 100010
    #define sl ((x)<<1)
    #define sr ((x)<<1|1)
    using namespace std;
    int n;
    int head[MAXN],nxt[MAXN*2],vv[MAXN*2],tot;
    inline void add_edge(int u, int v){
        vv[++tot]=v;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    int dfn[MAXN],cnt,sz[MAXN];
    void dfs(int u){
        dfn[u]=++cnt;
        sz[u]=1;
        for(register int i=head[u];i;i=nxt[i]){
            int v=vv[i];
            if(dfn[v]!=0) continue;
            dfs(v);
            sz[u]+=sz[v];
        }
    }
    struct nod{
        int l, r, val, lazy;
    } tre[MAXN*4];
    void built(int x, int l, int r){
        tre[x].l=l,tre[x].r=r;
        if(l==r) return;
        int mid=(l+r)>>1;
        built(sl, l, mid);
        built(sr, mid+1, r);
    }
    void push_down(int x){
        if(tre[x].lazy==0) return;
        tre[sl].lazy+=tre[x].lazy;
        tre[sr].lazy+=tre[x].lazy;
        tre[sl].val+=tre[x].lazy*(tre[sl].r-tre[sl].l+1);
        tre[sr].val+=tre[x].lazy*(tre[sr].r-tre[sr].l+1);
        tre[x].lazy=0;
    }
    void change(int x, int l, int r, int val){
        if(l<=tre[x].l&&tre[x].r<=r){
            tre[x].val+=val*(tre[x].r-tre[x].l+1);
            tre[x].lazy+=val;
            return;
        }
        push_down(x);
        int mid=(tre[x].l+tre[x].r)>>1;
        if(l<=mid) change(sl, l, r, val);
        if(r>mid) change(sr, l, r, val);
        tre[x].val=tre[sl].val+tre[sr].val;
    }
    int query(int x, int q){
        if(tre[x].l==tre[x].r) return tre[x].val;
        push_down(x);
        int mid=(tre[x].l+tre[x].r)>>1;
        if(q<=mid) return query(sl, q);
        else return query(sr, q);
    }
    int main()
    {
        scanf("%d", &n);
        for(int i=1;i<=n-1;++i){
            int a,b;scanf("%d %d", &a, &b);
            add_edge(a,b);
            add_edge(b,a);
        }
        dfs(1);
        built(1,1,n);
        for(int i=1;i<=n;++i){
            int q;scanf("%d", &q);
            printf("%d
    ", query(1, dfn[q]));
            change(1, dfn[q], dfn[q]+sz[q]-1, 1);
        }
        return 0;
    }
    
  • 相关阅读:
    SQL 语句添加约束
    sql server 的表进行设计后保存不了,一下方法可以解决
    约束的类型大全Sql server视图创建
    Python求和
    冒泡排序
    Python连接M有SQL,新增操作
    Python连接MYSQL,并做查询操作
    Python实现水仙花数
    测试工程师的一些面试题目(python)
    转:用Python解答百度测试开发算法面试题
  • 原文地址:https://www.cnblogs.com/santiego/p/10987232.html
Copyright © 2011-2022 走看看