zoukankan      html  css  js  c++  java
  • bzoj3307: 雨天的尾巴

    Star_Feel大爷是最强的

    这道题我的想法是把每种数字分开做,然后再合并

    现在不知道为什么就写了这种树上差分+下标是数字的线段树合并(其实都一样)

    那就这样吧

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    
    #define mid (ql+qr)/2
    using namespace std;
    const int _=1e2;
    const int maxn=1e5+_;
    const int bit=30;
    
    //---------------------------------------def-----------------------------------------------------
    
    struct node
    {
        int x,y,next;
    }a[2*maxn];int len,last[maxn];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int Bin[bit],f[bit][maxn],dep[maxn];
    void dfs(int x)
    {
        for(int i=1;dep[x]>=Bin[i];i++)f[i][x]=f[i-1][f[i-1][x]];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=f[0][x])
            {
                f[0][y]=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=25;i>=0;i--)
            if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
        if(x==y)return x;
        
        for(int i=25;i>=0;i--)
            if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y];
        return f[0][x];
    }
    
    //---------------------------------------prepare-----------------------------------------------------
    
    struct trnode
    {
        int lc,rc,mx,id;
    }tr[maxn*60];int trlen,rt[maxn];
    void update(int now)
    {
        int lc=tr[now].lc,rc=tr[now].rc;
        if(tr[lc].mx>=tr[rc].mx||rc==0)
            tr[now].mx=tr[lc].mx,tr[now].id=tr[lc].id;
        else
            tr[now].mx=tr[rc].mx,tr[now].id=tr[rc].id;
    }
    //~~~~~~~~~~~~~~~~~in~~~~~~~~~~~~~~~~~~~~
    
    int change(int now,int ql,int qr,int p,int d)
    {
        if(now==0)now=++trlen,tr[now].mx=ql==qr?0:-(1<<30);
        if(ql==qr){tr[now].mx+=d;tr[now].id=p;return now;}
        if(p<=mid)tr[now].lc=change(tr[now].lc,ql,mid,p,d);
        else tr[now].rc=change(tr[now].rc,mid+1,qr,p,d);
        update(now);return now;
    }
    int merge(int x,int y,int ql,int qr)
    {
        if(x==0||y==0)return x+y;
        if(ql==qr){tr[x].mx+=tr[y].mx;return x;}
        tr[x].lc=merge(tr[x].lc,tr[y].lc,ql,mid);
        tr[x].rc=merge(tr[x].rc,tr[y].rc,mid+1,qr);
        update(x);return x;
    }
    //~~~~~~~~~~~~~~~~~out~~~~~~~~~~~~~~~~~~~~
    
    //---------------------------------------segtree-----------------------------------------------------
    
    struct query{int x,y,p;}q[maxn];
    int lslen,ls[maxn];
    int as[maxn];
    void solve(int x)
    {
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=f[0][x])
            {
                solve(y);
                rt[x]=merge(rt[x],rt[y],1,lslen);
            }
        }
        as[x]=ls[tr[rt[x]].id];
    }
    int main()
    {
        int n,m,x,y,p;
        scanf("%d%d",&n,&m); len=1;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            ins(x,y),ins(y,x);
        }
        Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2;
        dfs(1);
        
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].p),ls[++lslen]=q[i].p;
        sort(ls+1,ls+lslen+1);
        lslen=unique(ls+1,ls+lslen+1)-ls-1;
        for(int i=1;i<=m;i++)
            q[i].p=lower_bound(ls+1,ls+lslen+1,q[i].p)-ls;
        
        trlen=0;
        for(int i=1;i<=m;i++)
        {
            x=q[i].x,y=q[i].y,p=q[i].p;
            int lca=LCA(x,y);
            rt[x]=change(rt[x],1,lslen,p,1);
            rt[y]=change(rt[y],1,lslen,p,1);
            rt[lca]=change(rt[lca],1,lslen,p,-1);
            if(lca!=1)rt[f[0][lca]]=change(rt[f[0][lca]],1,lslen,p,-1);
        }
        solve(1);
        for(int i=1;i<=n;i++)printf("%d
    ",as[i]);
        
        return 0;
    }
  • 相关阅读:
    Luogu P4002 [清华集训2017]生成树计数
    Luogu P3978 [TJOI2015]概率论
    Codechef JADUGAR2 Chef and Same Old Recurrence 2
    Codechef TREDEG Trees and Degrees
    一些有趣的数
    有向图上Euler回路计数
    P5105 不强制在线的动态快速排序
    二分图小结
    BZOJ2648: SJY摆棋子
    P3231 [HNOI2013]消毒
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10345251.html
Copyright © 2011-2022 走看看