BZOJ 3083 遥远的国度
Posted ziliuziliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\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 遥远的国度的主要内容,如果未能解决你的问题,请参考以下文章