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

    有了线段树合并的基础后,很容易想到差分最后线段树合并。

    这道题跟hdu上的relief grain是重题,然而我们老师却把那道题当做树剖的练手题给我们。

    害得我想了好久……

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2*1e5+10;
    int n,m,cnt;
    int beg[maxn],nex[maxn<<1],to[maxn<<1],e;
    inline void add(int x,int y){
        e++;nex[e]=beg[x];
        beg[x]=e;to[e]=y;
    }
    int dep[maxn],f[maxn][20];
    struct node{
        int l,r,ans,sum;
    }tr[maxn*50];
    int rt[maxn],ans[maxn]; 
    inline void dfs(int x,int fa){
        dep[x]=dep[fa]+1;
        f[x][0]=fa;
        for(int i=1;i<=19;i++)
            f[x][i]=f[f[x][i-1]][i-1];
        for(int i=beg[x];i;i=nex[i])
            if(to[i]!=fa)dfs(to[i],x);
    }
    inline int lca(int x,int y){
        if(dep[x]<dep[y])swap(x,y);
        for(int i=19;i>=0;i--)
            if(dep[x]-(1<<i)>=dep[y])
                x=f[x][i];
        if(x==y)return x;
        for(int i=19;i>=0;i--)
            if(f[x][i]!=f[y][i]){
                x=f[x][i];
                y=f[y][i];
            }
        return f[x][0];
    }
    inline void pushup(int now){
        if(tr[tr[now].l].sum>=tr[tr[now].r].sum){
            tr[now].sum=tr[tr[now].l].sum;
            tr[now].ans=tr[tr[now].l].ans;
        }else{
            tr[now].sum=tr[tr[now].r].sum;
            tr[now].ans=tr[tr[now].r].ans;
        }
    }
    inline void update(int &now,int l,int r,int x,int val){
        if(!now)now=++cnt;
        if(l==r){
            tr[now].sum+=val;
            tr[now].ans=l;
            return;
        }
        int mid=(l+r)>>1;
        if(mid>=x)update(tr[now].l,l,mid,x,val);
        else update(tr[now].r,mid+1,r,x,val);
        pushup(now);
    }
    inline int merge(int a,int b,int l,int r){
        if(!a)return b;
        if(!b)return a;
        if(l==r){
            tr[a].sum+=tr[b].sum;
            tr[a].ans=l;
            return a;
        }
        int mid=(l+r)>>1;
        tr[a].l=merge(tr[a].l,tr[b].l,l,mid);
        tr[a].r=merge(tr[a].r,tr[b].r,mid+1,r);
        pushup(a);
        return a;
    }
    inline void solve(int x,int fa){
        for(int i=beg[x];i;i=nex[i]){
            int t=to[i];
            if(t==fa)continue;
            solve(t,x);
            merge(rt[x],rt[t],1,maxn);
        }
        ans[x]=tr[rt[x]].ans;
        if(tr[rt[x]].sum==0)ans[x]=0;
    }
    inline int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*f;
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++)rt[i]=i;
        int x,y,z;
        for(int i=1;i<n;i++){
            x=read(),y=read();
            add(x,y),add(y,x);
        }
        dfs(1,0);cnt=n;
        for(int i=1;i<=m;i++){
            x=read(),y=read(),z=read();
            int t=lca(x,y);
            //printf("%d
    ",t);
            update(rt[x],1,maxn,z,1);
            update(rt[y],1,maxn,z,1);
            update(rt[t],1,maxn,z,-1);
            if(f[t][0])update(rt[f[t][0]],1,maxn,z,-1);
        }
        solve(1,0);
        for(int i=1;i<=n;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }

    深深地感到自己的弱小。

  • 相关阅读:
    Sql中关于日期的格式化
    linq中存储过程返回集合存在的问题
    当页面请求数据是从静态页中获取的Post方法会报405的错误
    jquery中load方法在ie下会卡住
    jquery用div实现下拉列表的效果
    jquery获取服务器端控件的方法
    【转】jquery实现文本框有提示输入的信息
    toString()方法浅谈
    Object类与上下转型
    多态
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12584680.html
Copyright © 2011-2022 走看看