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 ;
}

最新文章

  1. git 常用命令粗略总结
  2. ZJOIDay2T1 BB题解
  3. oracle免安装客户端设置
  4. PDF表单域(FormField)在HTML显示与提交数据到服务器
  5. SQL各种连接查询详解(左连接、右连接..)
  6. 非模态对话框的PreTranslateMessage() 没有用,无法进去
  7. 获取用户ip接口
  8. ASP长文章分页的两个方法,函数
  9. [Django 1.5] Windows + Apache + wsgi配置
  10. leetcode算法:Trim a Binar Search Tree
  11. 华科机考:N阶楼梯上楼
  12. Android Studio 错误 Duplicate files copied in APK META-INF/LICENSE.txt解决方案
  13. html转markdown网站
  14. (转)Spring Boot(十六):使用 Jenkins 部署 Spring Boot
  15. A1098. Insertion or Heap Sort
  16. bean的实例化方式
  17. 关于对springboot程序配置文件使用jasypt开源工具自定义加密
  18. leetcode [34] Find First and Last Position of Element in Sorted Array
  19. ubuntu14.04 解析不了域名—ubuntu的DNS配置
  20. Publish over SSH插件安装

热门文章

  1. 使用 polyfills 的简易方法
  2. codeforces 425B Sereja and Table(状态压缩,也可以数组模拟)
  3. iOS第三方推送-极光推送
  4. 数据库链接 mysql,sqlserver
  5. odata
  6. 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序
  7. 根据ip查询地区,经纬度等-geoip2
  8. 302. Smallest Rectangle Enclosing Black Pixels
  9. ExtJS4之Ext.MessageBox的各种用法
  10. win8找到程序员计算器