我们考虑树剖,线段树上维护一个堆,保存不经过该段区间的路径的权值。 
对于一条路径我们将对于线段树中的区间提取出来,在对于线段树中进行修改。也就是在堆中插入或删除。 
对于一次询问,只要找到包含该点的线段中堆顶权值最大的就行了。

 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std; typedef long long LL; #define N 200010 struct data
{
int l,r;
}q[N]; struct edge
{
int s,to,next;
}e[N<<];
int head[N<<];
int cnt; int dep[N],siz[N],son[N],top[N],pos[N];
int fa[N][],val[N<<]; bool vis[N]; int n,m;
int ans,res,num; int askd; struct cmp
{
bool operator() (int a,int b)
{
return val[a]<val[b];
}
}; priority_queue<int,vector<int>,cmp> Q[N<<]; bool cmp(data a,data b)
{
return a.l<b.l;
} void link(int x,int y)
{
e[++cnt]=(edge){x,y,head[x]};
head[x]=cnt;
} void dfs(int x)
{
siz[x]=;
son[x]=;
for (int i=head[x];i;i=e[i].next)
{
int t=e[i].to;
if (t!=fa[x][])
{
dep[t]=dep[x]+;
fa[t][]=x;
dfs(t);
siz[x]+=siz[t];
if (siz[t]>siz[son[x]])
son[x]=t;
}
}
} void dfs2(int x,int cha)
{
pos[x]=++res;
top[x]=cha;
if (son[x])
dfs2(son[x],cha);
for (int i=head[x];i;i=e[i].next)
{
int t=e[i].to;
if (t!=fa[x][] && t!=son[x])
dfs2(t,t);
}
} void build_lca()
{
for (int j=;j<=;j++)
for (int i=;i<=n;i++)
if (fa[i][j-])
fa[i][j]=fa[fa[i][j-]][j-];
} int lca(int x,int y)
{
if (dep[x]<dep[y])
swap(x,y);
int t=dep[x]-dep[y];
for (int i=;i>=;i--)
if (t & (<<i))
x=fa[x][i];
if (x==y)
return x;
for (int i=;i>=;i--)
if (fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][];
} void add(int nowl,int nowr,int now,int l,int r,int d)
{
if (l<=nowl && nowr<=r)
{
Q[now].push(d);
return ;
}
int mid=(nowl+nowr)>>;
if (l<=mid)
add(nowl,mid,now<<,l,r,d);
if (r>=mid+)
add(mid+,nowr,now<<|,l,r,d);
} void query(int nowl,int nowr,int now,int d)
{
while (!Q[now].empty())
{
int k=Q[now].top();
if (vis[k])
Q[now].pop();
else
{
num=max(num,val[k]);
break;
}
}
if (nowl==nowr)
return ;
int mid=(nowl+nowr)>>;
if (d<=mid)
query(nowl,mid,now<<,d);
else
query(mid+,nowr,now<<|,d);
}
int main()
{
scanf("%d%d",&n,&m);
int x,y;
for (int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
link(x,y);
link(y,x);
}
dep[]=;
dfs();
dfs2(,);
build_lca();
for (int i=;i<=m;i++)
{
scanf("%d",&askd);
if (askd==)
{
scanf("%d%d%d",&x,&y,&val[i]);
int w=,z=lca(x,y);
while (dep[top[x]]>dep[z])
{
q[++w]=(data){pos[top[x]],pos[x]};
x=fa[top[x]][];
}
while (dep[top[y]]>dep[z])
{
q[++w]=(data){pos[top[y]],pos[y]};
y=fa[top[y]][];
}
if (x!=z)
q[++w]=(data){pos[z],pos[x]};
else if (y!=z)
q[++w]=(data){pos[z],pos[y]};
else
q[++w]=(data){pos[z],pos[z]};
q[++w]=(data){n+,n+};
sort(q+,q+w+,cmp);
for (int j=;j<=w;j++)
if (q[j-].r<q[j].l-)
add(,n,,q[j-].r+,q[j].l-,i);
}
else if (askd==)
{
scanf("%d",&x);
vis[x]=;
}
else
{
scanf("%d",&x);
num=-;
query(,n,,pos[x]);
printf("%d\n",num);
}
}
return ;
}

最新文章

  1. Eclipse中进行Gradle+Jetty部署的web项目的断点调试
  2. 总结 | 如何测试你自己的 RubyGem
  3. struts2源代码学习之初始化(一)
  4. SQLServer获取最后插入的ID值SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY的比较
  5. phonegap与google analytics整合
  6. SOJ 1210 二叉树
  7. WebService入门实例教程
  8. java中String类学习笔记
  9. A*算法详解链接
  10. C# 递归省市区三级树结构
  11. Zabbix3.x 监控磁盘IO与自定义模板
  12. Luogu2264 树上游戏(点分治)
  13. sqler sql 转rest api 的工具试用
  14. class对象存储
  15. springcloud- FeginClient 调用统一拦截添加请求头 RequestInterceptor ,被调用服务获取请求头
  16. 一:Shiro知识整理
  17. 方格取数(dp)
  18. 使用openresty + lua 搭建api 网关(一)安装openresty ,并添加lua模块
  19. openssl之BIO系列之22---Cipher类型的BIO
  20. 对比java和python对比

热门文章

  1. springboot实现web应用过程中的摸爬打滚(持续更新ing)
  2. React入门介绍(2)- React Component-React组件
  3. Python使用Flask框架,结合Highchart,自定义导出菜单项目及顺序
  4. impdp导入
  5. CSS九宫格样式
  6. MyBaties 异常之 java.lang.UnsupportedOperationException
  7. layer弹层content写错导致div复制了一次,导致id失效 $().val() 获取不到dispaly:none div里表单的值
  8. 开启POP3/SMTP服务
  9. HDU 1564 找规律博弈
  10. [TyvjP1050] 最长公共子序列(DP)