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

    传送门

    树上差分+线段树合并+离散化
    对于修改的路径,树上差分就好了
    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<tr1/unordered_map>
    #include<algorithm>
    using namespace std;
    void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=1e5+10;
    int dep[maxn],n,m,id,tot,pre[maxn*2],rt[maxn],ls[maxn*50],f[maxn][20],x[maxn],y[maxn],z[maxn],nid[maxn];
    int rs[maxn*50],mx[maxn*50],mxid[maxn*50],nxt[maxn*2],h[maxn],cnt,ans[maxn],w[maxn];tr1::unordered_map<int,int>mp;
    bool vis[maxn];
    void add(int x,int y)
    {
        pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;
        pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt;
    }
    void dfs(int x,int fa)
    {
        for(rg int i=1;i<20;i++)
        {
            if((1<<i)>dep[x])break;
            f[x][i]=f[f[x][i-1]][i-1];
        }
        for(rg int i=h[x];i;i=nxt[i])
            if(pre[i]!=fa)f[pre[i]][0]=x,dep[pre[i]]=dep[x]+1,dfs(pre[i],x);
    }
    int lca(int x,int y)
    {
        if(dep[x]>dep[y])swap(x,y);
        int poor=dep[y]-dep[x];
        for(rg int i=19;i>=0;i--)if(poor&(1<<i))y=f[y][i];
        if(x==y)return x;
        for(rg int i=19;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
        return x==y?x:f[x][0];
    }
    void update(int x)
    {
        if(mx[ls[x]]>mx[rs[x]]||(mx[ls[x]]==mx[rs[x]]&&mxid[ls[x]]<mxid[rs[x]]))mx[x]=mx[ls[x]],mxid[x]=mxid[ls[x]];
        else if(mx[ls[x]]<mx[rs[x]]||(mx[ls[x]]==mx[rs[x]]&&mxid[ls[x]]>mxid[rs[x]]))mx[x]=mx[rs[x]],mxid[x]=mxid[rs[x]];
    }
    void change(int &k,int l,int r,int a,int b)
    {
        if(!k)k=++id;int mid=(l+r)>>1;
        if(l==r){mx[k]+=b,mxid[k]=mx[k]?l:0;return ;}
        if(a<=mid)change(ls[k],l,mid,a,b);
        else change(rs[k],mid+1,r,a,b);
        update(k);
    }
    int merge(int x,int y,int l,int r)
    {
        if(!x||!y)return x+y;
        int mid=(l+r)>>1;
        ls[x]=merge(ls[x],ls[y],l,mid);
        rs[x]=merge(rs[x],rs[y],mid+1,r);
        if(l==r)mx[x]+=mx[y],mxid[x]=mx[x]?l:0;else update(x);
        return x;
    }
    void solve(int x,int fa)
    {
        for(rg int i=h[x];i;i=nxt[i])
            if(pre[i]!=fa)
            {
                solve(pre[i],x);
                rt[x]=merge(rt[x],rt[pre[i]],1,tot);
            }
        ans[x]=nid[mxid[rt[x]]];
    }
    int main()
    {
        read(n),read(m);
        for(rg int i=1,x,y;i<n;i++)read(x),read(y),add(x,y);
        dfs(1,0);
        for(rg int i=1;i<=m;i++)read(x[i]),read(y[i]),read(z[i]),w[i]=z[i];
        sort(w+1,w+m+1);
        for(rg int i=1;i<=m;i++)if(!mp[w[i]])mp[w[i]]=++tot,nid[tot]=w[i];
        for(rg int i=1;i<=m;i++)
        {
            int fa=lca(x[i],y[i]);
            change(rt[x[i]],1,tot,mp[z[i]],1),change(rt[y[i]],1,tot,mp[z[i]],1),
            change(rt[fa],1,tot,mp[z[i]],-1),change(rt[f[fa][0]],1,tot,mp[z[i]],-1);
        }
        solve(1,0);
        for(rg int i=1;i<=n;i++)printf("%d
    ",ans[i]);
    }
    
  • 相关阅读:
    windows环境下的python2.6 安装pydelicious API的正确方法与步骤
    2、提供推荐
    python的os.path.join()
    ompl_interface/OMPLPlanner
    ros moveit 安装
    ipv6 duplicate address detected
    python版本原因导致不能安装和卸载软件
    RoboWare Viewer安装可能出现的问题
    npm install 时卡在了node-gyp rebuild
    npm install 出错
  • 原文地址:https://www.cnblogs.com/lcxer/p/10604150.html
Copyright © 2011-2022 走看看