首页 > 代码库 > BZOJ 3083 遥远的国度

BZOJ 3083 遥远的国度

链剖水题。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxv 100500#define maxe 200500#define inf 2147483647using 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\n",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\n",min(ask(root,1,n,1,l),ask(root,1,n,r,n)));    }    else        printf("%d\n",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;}

 

BZOJ 3083 遥远的国度