您的位置:首页 > 其它

BZOJ 3306 树

2016-08-26 12:09 267 查看
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=0,x,y,cnt=0,dis[maxv],mx[maxv],anc[maxv][23];
int tot=0,root,ls[maxv<<2],rs[maxv<<2],val[maxv<<2],nrt;
char s[4];
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]+1;
dfs(v,x);anc[v][0]=x;
mx[x]=max(mx[x],mx[v]);
}
}
void get_table()
{
for (int e=1;e<=20;e++)
for (int i=1;i<=n;i++)
anc[i][e]=anc[anc[i][e-1]][e-1];
}
void build(int &now,int left,int right)
{
now=++tot;
if (left==right)
{
val[now]=w[fdfn[left]];
return;
}
int mid=(left+right)>>1;
build(ls[now],left,mid);
build(rs[now],mid+1,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)>>1;
if (pos<=mid) modify(ls[now],left,mid,pos);
else modify(rs[now],mid+1,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<=0) || (r>=n+1)) return inf;
if ((left==l) && (right==r)) return val[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));
}
int find(int x,int pos)
{
for (int e=20;e>=0;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=1;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&x,&w[i]);
if (x!=0) {addedge(i,x);addedge(x,i);}
}
dfs(1,1);
get_table();
build(root,1,n);
for (int i=1;i<=m;i++)
{
scanf("%s",s);
if (s[0]=='V')
{
scanf("%d%d",&x,&y);
w[x]=y;
modify(root,1,n,dfn[x]);
}
else if (s[0]=='E') scanf("%d",&nrt);
else
{
scanf("%d",&x);
if (x==nrt) printf("%d\n",val[1]);
else if ((dfn[nrt]>=dfn[x]) && (dfn[nrt]<=mx[x]))
{
int r=find(nrt,x);
printf("%d\n",min(ask(root,1,n,1,dfn[r]-1),ask(root,1,n,mx[r]+1,n)));
}
else printf("%d\n",ask(root,1,n,dfn[x],mx[x]));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: