zoukankan      html  css  js  c++  java
  • BZOJ 3083 遥远的国度

    链剖水题。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 100500
    #define maxe 200500
    #define inf 2147483647
    using namespace std;
    int n,m,type,x,y,z,val[maxv],id=1,g[maxv],nume=0;
    int w[maxv],fw[maxv],dis[maxv],fath[maxv],top[maxv],size[maxv],son[maxv],mx[maxv],times=0;
    int root,tot=0,ls[maxv<<2],rs[maxv<<2],mn[maxv<<2],lazy[maxv<<2];
    struct edge
    {
        int v,nxt;
    }e[maxe];
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void dfs1(int x,int father)
    {
        size[x]=1;son[x]=0;
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=father)
            {
                fath[v]=x;dis[v]=dis[x]+1;
                dfs1(v,x);
                size[x]+=size[v];
                if (size[v]>size[son[x]]) son[x]=v;
            }
        }
    }
    void dfs2(int x,int father)
    {
        w[x]=mx[x]=++times;fw[times]=x;top[x]=father;
        if (son[x]) {dfs2(son[x],father);mx[x]=max(mx[x],mx[son[x]]);}
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if ((v!=fath[x]) && (v!=son[x]))
            {
                dfs2(v,v);
                mx[x]=max(mx[x],mx[v]);
            }
        }
    }
    void build(int &now,int left,int right)
    {
        now=++tot;lazy[now]=inf;
        if (left==right)
        {
            mn[now]=val[fw[left]];
            return;
        }
        int mid=left+right>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
        mn[now]=min(mn[ls[now]],mn[rs[now]]);
    }
    void pushdown(int now)
    {
        if (lazy[now]==inf) return;
        lazy[ls[now]]=lazy[rs[now]]=mn[ls[now]]=mn[rs[now]]=lazy[now];
        lazy[now]=inf;
    }
    void modify(int now,int left,int right,int l,int r,int x)
    {
        pushdown(now);
        if ((left==l) && (right==r))
        {
            lazy[now]=x;mn[now]=x;
            return;
        }
        int mid=left+right>>1;
        if (r<=mid) modify(ls[now],left,mid,l,r,x);
        else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,x);
        else
        {
            modify(ls[now],left,mid,l,mid,x);
            modify(rs[now],mid+1,right,mid+1,r,x);
        }
        mn[now]=min(mn[ls[now]],mn[rs[now]]);
    }
    void line_modify()
    {
        int f1=top[x],f2=top[y];
        while (f1!=f2)
        {
            if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);}
            modify(root,1,n,w[f1],w[x],z);
            x=fath[f1];f1=top[x];
        }
        if (dis[x]>dis[y]) swap(x,y);
        modify(root,1,n,w[x],w[y],z);
    }
    int lca(int x,int y)
    {
        int f1=top[x],f2=top[y];
        while (f1!=f2)
        {
            if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);}
            x=fath[f1];f1=top[x];
        }
        if (dis[x]<dis[y]) return x;
        return y;
    }
    int lca2(int x,int pos)
    {
        int f1=top[x],f2=top[pos],ret;
        while (f1!=f2) {ret=f1;x=fath[f1];f1=top[x];}
        if (x==pos) return ret;
        else return son[pos];
    }
    int ask(int now,int left,int right,int l,int r)
    {
        if (l>r) return inf;
        pushdown(now);
        if ((left==l) && (right==r))
            return mn[now];
        int mid=left+right>>1;
        if (r<=mid) return ask(ls[now],left,mid,l,r);
        else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r);
        else return min(ask(ls[now],left,mid,l,mid),ask(rs[now],mid+1,right,mid+1,r));
    }
    void line_ask()
    {
        int t=lca(id,x);
        if (id==x)
            printf("%d
    ",ask(root,1,n,1,n));
        else if (t==x)
        {
            int pos=lca2(id,x);
            int l=w[pos]-1,r=mx[pos]+1;
            printf("%d
    ",min(ask(root,1,n,1,l),ask(root,1,n,r,n)));
        }
        else
            printf("%d
    ",ask(root,1,n,w[x],mx[x]));
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n-1;i++)
        {
            scanf("%d%d",&x,&y);
            addedge(x,y);addedge(y,x);
        }
        for (int i=1;i<=n;i++) scanf("%d",&val[i]);
        scanf("%d",&id);
        dfs1(1,1);
        dfs2(1,1);
        build(root,1,n);
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&type);
            if (type==1) scanf("%d",&id);
            else if (type==2)
            {
                scanf("%d%d%d",&x,&y,&z);
                line_modify();
            }
            else
            {
                scanf("%d",&x);
                line_ask();
            }
        }
        return 0;
    }
  • 相关阅读:
    android 打包错误
    mysql innoDB 挂了的临时解决方案
    android notification 传值关键
    maven eclipse 插件下载地址
    微信html5开发选哪一个
    android AsyncTask 只能在线程池里单个运行的问题
    关于Fragment 不响应onActivityResult的情况分析 (
    Android-BaseLine基础性开发框架
    linux网络流量实时监控工具之iptraf
    android 圆角按钮和按钮颜色
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5869482.html
Copyright © 2011-2022 走看看