BZOJ 3306 树

时间:2023-03-09 06:26:33
BZOJ 3306 树

dfs序建线段树+分类讨论+写的有点长。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 100500
#define maxe 200500
#define inf 2147483646
using namespace std;
int n,m,w[maxv],dfn[maxv],fdfn[maxv],g[maxv],nume=,x,y,cnt=,dis[maxv],mx[maxv],anc[maxv][];
int tot=,root,ls[maxv<<],rs[maxv<<],val[maxv<<],nrt;
char s[];
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 dfs(int x,int fath)
{
dfn[x]=++cnt;mx[x]=dfn[x];fdfn[cnt]=x;
for (int i=g[x];i;i=e[i].nxt)
{
int v=e[i].v;
if (v==fath) continue;
dis[v]=dis[x]+;
dfs(v,x);anc[v][]=x;
mx[x]=max(mx[x],mx[v]);
}
}
void get_table()
{
for (int e=;e<=;e++)
for (int i=;i<=n;i++)
anc[i][e]=anc[anc[i][e-]][e-];
}
void build(int &now,int left,int right)
{
now=++tot;
if (left==right)
{
val[now]=w[fdfn[left]];
return;
}
int mid=(left+right)>>;
build(ls[now],left,mid);
build(rs[now],mid+,right);
val[now]=min(val[ls[now]],val[rs[now]]);
}
void modify(int now,int left,int right,int pos)
{
if ((left==right) && (left==pos))
{
val[now]=w[fdfn[left]];
return;
}
int mid=(left+right)>>;
if (pos<=mid) modify(ls[now],left,mid,pos);
else modify(rs[now],mid+,right,pos);
val[now]=min(val[ls[now]],val[rs[now]]);
}
int ask(int now,int left,int right,int l,int r)
{
if (l>r) return inf;
if ((l<=) || (r>=n+)) return inf;
if ((left==l) && (right==r)) return val[now];
int mid=(left+right)>>;
if (r<=mid) return ask(ls[now],left,mid,l,r);
else if (l>=mid+) return ask(rs[now],mid+,right,l,r);
else return min(ask(ls[now],left,mid,l,mid),ask(rs[now],mid+,right,mid+,r));
}
int find(int x,int pos)
{
for (int e=;e>=;e--)
{
if (dis[anc[x][e]]>dis[pos])
x=anc[x][e];
}
return x;
}
int main()
{
freopen("cin.in","r",stdin);
freopen("a.out","w",stdout);
nrt=;
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++)
{
scanf("%d%d",&x,&w[i]);
if (x!=) {addedge(i,x);addedge(x,i);}
}
dfs(,);
get_table();
build(root,,n);
for (int i=;i<=m;i++)
{
scanf("%s",s);
if (s[]=='V')
{
scanf("%d%d",&x,&y);
w[x]=y;
modify(root,,n,dfn[x]);
}
else if (s[]=='E') scanf("%d",&nrt);
else
{
scanf("%d",&x);
if (x==nrt) printf("%d\n",val[]);
else if ((dfn[nrt]>=dfn[x]) && (dfn[nrt]<=mx[x]))
{
int r=find(nrt,x);
printf("%d\n",min(ask(root,,n,,dfn[r]-),ask(root,,n,mx[r]+,n)));
}
else printf("%d\n",ask(root,,n,dfn[x],mx[x]));
}
}
return ;
}