• BZOJ3307: 雨天的尾巴


    【传送门:BZOJ3307


    简要题意:

      给出一棵n个点的树,有m个操作

      每个操作输入x,y,z,表示x到y的路径上的所有点都放一个编号为z的物品

      最后输出每个点存放最多的物品是哪个(如果有存放数量相同的物品,输出编号小的)


    题解:

      对于每种操作相当于区间增值,那就树上差分,而因为物品不同,所以每个点都用主席树来维护

      主席树上的叶子节点为物品,点权为出现的数量

      然后求答案的时候从叶子节点向上合并主席树就行了,因为合并之后的主席树的叶子节点的点权肯定都是>=0

      所以在合并之后再更新最大值就行了

      PS:这题有点小卡空间


    参考代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #define Maxn 110000
    using namespace std;
    struct node{int x,y,next;}a[Maxn*2];int len,last[Maxn];
    void ins(int x,int y){a[++len]=(node){x,y,last[x]};last[x]=len;}
    int f[Maxn][21],dep[Maxn];
    void dfs(int x)
    {
        for(int i=1;dep[x]>=(1<<i);i++)
        {
            f[x][i]=f[f[x][i-1]][i-1];
        }
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y==f[x][0]) continue;
            f[y][0]=x;
            dep[y]=dep[x]+1;
            dfs(y);
        }
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y]) swap(x,y);
        for(int i=20;i>=0;i--)
        {
            if(dep[x]-dep[y]>=(1<<i)) x=f[x][i];
        }
        if(x==y) return x;
        for(int i=20;i>=0;i--)
        {
            if(dep[x]>=(1<<i)&&f[x][i]!=f[y][i])
            {
                x=f[x][i];y=f[y][i];
            }
        }
        return f[x][0];
    }
    struct trnode{int lc,rc,mx;}tr[Maxn*60];int rt[Maxn],tot;
    void update(int u)
    {
        int lc=tr[u].lc,rc=tr[u].rc;
        if(lc!=0&&rc!=0)
        {
            if(tr[lc].mx>=tr[rc].mx) tr[u].mx=tr[lc].mx;
            else tr[u].mx=tr[rc].mx;
        }
        else if(lc!=0) tr[u].mx=tr[lc].mx;
        else if(rc!=0) tr[u].mx=tr[rc].mx;
    }
    void add(int &u,int x,int d,int l,int r)
    {
        if(u==0) u=++tot;
        if(l==r)
        {
            tr[u].mx+=d;
            return ;
        }
        int mid=(l+r)/2;
        if(x<=mid) add(tr[u].lc,x,d,l,mid);
        else add(tr[u].rc,x,d,mid+1,r);
        update(u);
    }
    void Merge(int &u1,int u2,int l,int r)
    {
        if(u1==0){u1=u2;return ;}
        if(u2==0) return ;
        if(l==r)
        {
            tr[u1].mx+=tr[u2].mx;
            return ;
        }
        int mid=(l+r)/2;
        Merge(tr[u1].lc,tr[u2].lc,l,mid);
        Merge(tr[u1].rc,tr[u2].rc,mid+1,r);
        update(u1);
    }
    struct query{int x,y,p,z;}Q[Maxn];int to[Maxn],p;
    bool cmp(query n1,query n2){return n1.z<n2.z;}
    int ans[Maxn];
    int gett(int u,int l,int r)
    {
        if(l==r) return l;
        int lc=tr[u].lc,rc=tr[u].rc,mid=(l+r)/2;
        if(tr[lc].mx>=tr[rc].mx) return gett(lc,l,mid);
        else return gett(rc,mid+1,r);
    }
    void solve(int x)
    {
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y==f[x][0]) continue;
            solve(y);
            Merge(rt[x],rt[y],1,p);
        }
        if(tr[rt[x]].mx<=0) ans[x]=0;
        else ans[x]=to[gett(rt[x],1,p)];
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            ins(x,y);ins(y,x);
        }
        dep[1]=1;f[1][0]=0;dfs(1);
        memset(rt,0,sizeof(rt));tot=0;
        for(int i=1;i<=m;i++) scanf("%d%d%d",&Q[i].x,&Q[i].y,&Q[i].z);
        sort(Q+1,Q+m+1,cmp);
        p=1;Q[1].p=p;to[1]=Q[1].z;
        for(int i=2;i<=m;i++)
        {
            if(Q[i].z!=Q[i-1].z) p++;
            Q[i].p=p;to[p]=Q[i].z;
        }
        for(int i=1;i<=m;i++)
        {
            int x=Q[i].x,y=Q[i].y,z=Q[i].p;
            int lca=LCA(x,y);
            add(rt[x],z,1,1,p);add(rt[y],z,1,1,p);add(rt[lca],z,-1,1,p);
            if(f[lca][0]!=0) add(rt[f[lca][0]],z,-1,1,p);
        }
        solve(1);
        for(int i=1;i<=n;i++) printf("%d
    ",ans[i]);
        return 0;
    }

     

  • 相关阅读:
    python报错Enable tracemalloc to get the object allocation traceback
    解决pycharm每次新建项目都要重新安装一些第三方库的问题
    创建一个CA证书
    [转载]oracle 12C 《服务器、客户端安装》
    [转载]Windows Server 2016中添加AD域控制器
    [转载]Windows Server 2016中部署AD
    虚拟机 VMware Workstation Pro 15.5.0 及永久激活密钥
    Oracle给查询结果增加序列号
    创建自定义ssl证书用于https
    js:getAttribute
  • 原文地址:https://www.cnblogs.com/Never-mind/p/9982561.html
Copyright © 2020-2023  润新知