• BZOJ 3653 谈笑风生


    ORZ blutrex。。。。。。

    主席树。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 1000500
    #define maxq 1000500
    #define maxe 1600500
    using namespace std;
    struct edge
    {
        long long v,nxt;
    }e[maxe];
    struct answer
    {
        long long sum1,sum2;
    };
    long long n,q,x,y,nume=0,g[maxv],size[maxv],dis[maxv],w[maxv],mx[maxv],mxdis=0,cnt=0,fw[maxv];
    long long root[maxv],ls[maxv<<3],rs[maxv<<3],val1[maxv<<3],val2[maxv<<3],tot=0;
    void addedge(long long u,long long v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void dfs(long long x,long long fath)
    {
        size[x]=1;w[x]=++cnt;mx[x]=w[x];fw[cnt]=x;
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if (v!=fath)
            {
                dis[v]=dis[x]+1;mxdis=max(mxdis,dis[v]);
                dfs(v,x);
                size[x]+=size[v];
                mx[x]=max(mx[x],mx[v]);
            }
        }
    }
    void build(long long &now,long long left,long long right)
    {
        now=++tot;val1[now]=val2[now]=0;
        if (left==right) return;
        long long mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
    }
    void modify(long long last,long long &now,long long left,long long right,long long pos,long long x)
    {
        now=++tot;ls[now]=ls[last];rs[now]=rs[last];
        val1[now]=val1[last]+x;val2[now]=val2[last]+1;
        if (left==right) return;
        long long mid=(left+right)>>1;
        if (pos<=mid) modify(ls[last],ls[now],left,mid,pos,x);
        else modify(rs[last],rs[now],mid+1,right,pos,x);
    }
    answer merge(answer x,answer y)
    {
        answer ret;
        ret.sum1=x.sum1+y.sum1;
        ret.sum2=x.sum2+y.sum2;
        return ret;
    }
    answer ask(long long last,long long now,long long left,long long right,long long l,long long r)
    {
        answer ret;
        if ((left==l) && (right==r))
        {
            ret.sum1=val1[now]-val1[last];
            ret.sum2=val2[now]-val2[last];
            return ret;
        }
        long long mid=(left+right)>>1;
        if (r<=mid) return ask(ls[last],ls[now],left,mid,l,r);
        else if (l>=mid+1) return ask(rs[last],rs[now],mid+1,right,l,r);
        else return merge(ask(ls[last],ls[now],left,mid,l,mid),ask(rs[last],rs[now],mid+1,right,mid+1,r));
    }
    int main()
    {
        scanf("%lld%lld",&n,&q);
        for (long long i=1;i<=n-1;i++)
        {
            scanf("%lld%lld",&x,&y);
            addedge(x,y);
            addedge(y,x);
        }
        dfs(1,1);
        build(root[0],0,mxdis);
        for (long long i=1;i<=n;i++)
            modify(root[i-1],root[i],0,mxdis,dis[fw[i]],size[fw[i]]);
        for (long long i=1;i<=q;i++)
        {
            scanf("%lld%lld",&x,&y);
            long long ret=min(dis[x],y)*(size[x]-1);
            answer regis=ask(root[w[x]-1],root[mx[x]],0,mxdis,min(dis[x]+1,mxdis),min(dis[x]+y,mxdis));
            ret+=regis.sum1-regis.sum2;
            printf("%lld
    ",ret);
        }
        return 0;
    }
  • 相关阅读:
    【转载】常考算法模板
    NOIP2020微信步数暴力80分
    NOIP2020移球游戏快速排序满分程序
    第一场NOI Online能力测试入门组B跑步
    【转】STL之Set——插入元素、二分查找元素(log级别)
    [转载]图论500题
    差分约束系统简单介绍(入门)
    辗转相除法的证明
    并查集2个优化——按秩合并和路径压缩
    递推算法之平面分割问题总结
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5674790.html
Copyright © 2020-2023  润新知