zoukankan      html  css  js  c++  java
  • 2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162

    题意:给出一棵树的链接方法,每个点都有一个数字,询问U-》V节点经过所有路径中l < = x < = r的数字和

    解法:主席树维护区间和,树剖查询,复杂度nloglog。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+5;
    const int maxm = 40*maxn;
    typedef long long LL;
    int T[maxn];
    int lson[maxm],rson[maxm];
    LL sum[maxm];
    int clk,M;
    int newnode(){
        clk++;
        lson[clk]=rson[clk]=sum[clk]=0;
        return clk;
    }
    void update(int &now, int pre, int L, int R, int pos, int val)
    {
        now = newnode();
        lson[now] = lson[pre];
        rson[now] = rson[pre];
        sum[now] = sum[pre] + val;
        if(L!=R){
            int mid=(L+R)>>1;
            if(pos<=mid) update(lson[now],lson[pre],L,mid,pos,val);
            else update(rson[now],rson[pre],mid+1,R,pos,val);
        }
    }
    LL query(int rt, int L, int R, int l, int r){
        if(l<=L&&R<=r){
            return sum[rt];
        }
        else{
            int mid = (L+R)>>1;
            LL ret = 0;
            if(l <= mid) ret += query(lson[rt], L, mid, l, r);
            if(mid < r) ret += query(rson[rt], mid+1, R, l, r);
            return ret;
        }
    }
    struct edge{
        int to,next;
    }E[maxn*2];
    int head[maxn],edgecnt,tim;
    int siz[maxn],top[maxn],son[maxn],dep[maxn];
    int fa[maxn],tid[maxn],Rank[maxn],val[maxn];
    void init(){
        edgecnt=tim=0;
        memset(head,-1,sizeof(head));
        memset(son,-1,sizeof(son));
        clk=M=0;
        lson[clk]=rson[clk]=sum[clk]=0;
    }
    void add(int u, int v){
        E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
    }
    void dfs1(int u, int pre, int d){
        dep[u]=d;
        fa[u]=pre;
        siz[u]=1;
        for(int i=head[u];~i;i=E[i].next){
            int v=E[i].to;
            if(v!=pre){
                dfs1(v,u,d+1);
                siz[u]+=siz[v];
                if(son[u]==-1||siz[v]>siz[son[u]]) son[u]=v;
            }
        }
    }
    void dfs2(int u, int tp){
        top[u]=tp;
        tid[u]=++tim;
        Rank[tid[u]]=u;
        if(son[u]==-1) return;
        dfs2(son[u],tp);
        for(int i=head[u];~i;i=E[i].next){
            int v=E[i].to;
            if(v!=son[u]&&v!=fa[u]){
                dfs2(v,v);
            }
        }
    }
    int LCA(int u, int v)
    {
        int ret;
        while(true)
        {
            if(top[u] == top[v])
            {
                ret = dep[u] < dep[v] ? u : v;
                break;
            }
            else if(dep[top[u]] > dep[top[v]])
                u = fa[top[u]];
            else v = fa[top[v]];
        }
        return ret;
    }
    int t[maxn];
    LL query(int u, int v, int a, int b)
    {
        a = lower_bound(t + 1, t + 1 + M, a) - t - 1;
        b = upper_bound(t + 1, t + 1 + M, b) - t - 1;
        if(b == 0)
            return 0;
        LL ret = 0;
        while(top[u] != top[v])
        {
            if(dep[top[u]] < dep[top[v]])
                swap(u, v);
            ret += query(T[tid[u]], 1, M, 1, b);
            ret -= query(T[tid[top[u]] - 1], 1, M, 1, b);
            if(a)
            {
                ret -= query(T[tid[u]], 1, M, 1, a);
                ret += query(T[tid[top[u]] - 1], 1, M, 1, a);
            }
            u = fa[top[u]];
        }
        if(dep[u] < dep[v])
            swap(u, v);
        ret += query(T[tid[u]], 1, M, 1, b);
        ret -= query(T[tid[v] - 1], 1, M, 1, b);
        if(a)
        {
            ret -= query(T[tid[u]], 1, M, 1, a);
            ret += query(T[tid[v] - 1], 1, M, 1, a);
        }
        return ret;
    }
    int main()
    {
        int n,m;
        while(~scanf("%d %d",&n,&m))
        {
            init();
            for(int i=1; i<=n; i++){
                scanf("%d", &val[i]);
                t[i]=val[i];
            }
            for(int i=1; i<n; i++){
                int u,v;
                scanf("%d %d", &u,&v);
                add(u, v);
                add(v, u);
            }
            dfs1(1,0,0);
            dfs2(1,1);
            sort(t+1,t+n+1);
            M = unique(t+1, t+n+1)-t-1;
            for(int i=1; i<=n; i++) val[i] = lower_bound(t+1, t+1+M, val[i])-t;
            for(int i=1; i<=n; i++){
                T[i] = T[i-1];
                update(T[i],T[i],1,M,val[Rank[i]],t[val[Rank[i]]]);
            }
            for(int i=1; i<=m; i++){
                int u,v,x,y;
                scanf("%d %d %d %d", &u,&v,&x,&y);
                LL ret = query(u,v,x,y);
                printf("%lld", ret);
                if(i == m){
                    printf("
    ");
                }
                else{
                    printf(" ");
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    ActiveSync合作关系对话框的配置
    WINCE对象存储区(object store)
    Wince 隐藏TASKBAR的方法
    Wince输入法换肤换语言机制
    poj 3080 Blue Jeans 解题报告
    codeforces A. Vasily the Bear and Triangle 解题报告
    hdu 1050 Moving Tables 解题报告
    hdu 1113 Word Amalgamation 解题报告
    codeforces A. IQ Test 解题报告
    poj 1007 DNA Sorting 解题报告
  • 原文地址:https://www.cnblogs.com/spfa/p/7418304.html
Copyright © 2011-2022 走看看