树链剖分,线段树维护~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; const int MAXN = ;
struct Edge
{
int to,next;
}edge[MAXN*];
int head[MAXN],tot;
int top[MAXN];//top[v]表示v所在的重链的顶端节点
int fa[MAXN]; //父亲节点
int deep[MAXN];//深度
int num[MAXN];//num[v]表示以v为根的子树的节点数
int p[MAXN];//p[v]表示v与其父亲节点的连边在线段树中的位置
int fp[MAXN];//和p数组相反
int son[MAXN];//重儿子
int pos;
void init()
{
tot = ;
memset(head,-,sizeof(head));
pos = ;
memset(son,-,sizeof(son));
}
void addedge(int u,int v)
{
edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
}
void dfs1(int u,int pre,int d) //第一遍dfs求出fa,deep,num,son
{
deep[u] = d;
fa[u] = pre;
num[u] = ;
for(int i = head[u];i != -; i = edge[i].next)
{
int v = edge[i].to;
if(v != pre)
{
dfs1(v,u,d+);
num[u] += num[v];
if(son[u] == - || num[v] > num[son[u]])
son[u] = v;
}
}
}
void getpos(int u,int sp) //第二遍dfs求出top和p
{
top[u] = sp;
if(son[u] != -)
{
p[u] = pos++;
fp[p[u]] = u;
getpos(son[u],sp);
}
else
{
p[u] = pos++;
fp[p[u]] = u;
return;
}
for(int i = head[u] ; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(v != son[u] && v != fa[u])
getpos(v,v);
}
} //线段树
struct Node
{
int l,r;
int Max;
}segTree[MAXN*];
void build(int i,int l,int r)
{
segTree[i].l = l;
segTree[i].r = r;
segTree[i].Max = ;
if(l == r)return;
int mid = (l+r)/;
build(i<<,l,mid);
build((i<<)|,mid+,r);
}
void push_up(int i)
{
segTree[i].Max = max(segTree[i<<].Max,segTree[(i<<)|].Max);
}
void update(int i,int k,int val) // 更新线段树的第k个值为val
{
if(segTree[i].l == k && segTree[i].r == k)
{
segTree[i].Max = val;
return;
}
int mid = (segTree[i].l + segTree[i].r)/;
if(k <= mid)update(i<<,k,val);
else update((i<<)|,k,val);
push_up(i);
}
int query(int i,int l,int r) //查询线段树中[l,r] 的最大值
{
if(segTree[i].l == l && segTree[i].r == r)
return segTree[i].Max;
int mid = (segTree[i].l + segTree[i].r)/;
if(r <= mid)return query(i<<,l,r);
else if(l > mid)return query((i<<)|,l,r);
else return max(query(i<<,l,mid),query((i<<)|,mid+,r));
}
int find(int u,int v)//查询u->v边的最大值
{
int f1 = top[u], f2 = top[v];
int tmp = ;
while(f1 != f2)
{
if(deep[f1] < deep[f2])
{
swap(f1,f2);
swap(u,v);
}
tmp = max(tmp,query(,p[f1],p[u]));
u = fa[f1]; f1 = top[u];
}
if(u == v)return tmp;
if(deep[u] > deep[v]) swap(u,v);
return max(tmp,query(,p[son[u]],p[v]));
}
int e[MAXN][];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int n;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
for(int i = ;i < n-;i++)
{
scanf("%d%d%d",&e[i][],&e[i][],&e[i][]);
addedge(e[i][],e[i][]);
addedge(e[i][],e[i][]);
}
dfs1(,,);
getpos(,);
build(,,pos-);
for(int i = ;i < n-; i++)
{
if(deep[e[i][]] > deep[e[i][]])
swap(e[i][],e[i][]);
update(,p[e[i][]],e[i][]);
}
char op[];
int u,v;
while(scanf("%s",op) == )
{
if(op[] == 'D')break;
scanf("%d%d",&u,&v);
if(op[] == 'Q')
printf("%d\n",find(u,v));
else update(,p[e[u-][]],v);
}
}
return ;
}

最新文章

  1. jdbc执行预处理,批处理,LOB字段处理,调用存储过程
  2. git 调用 Beyond Compare
  3. domReady方法(dom加载完成执行回调)
  4. C#将Json字符串反序列化成List对象类集合
  5. CentOS of MySQL command
  6. 学习C++——只声明忘记定义了
  7. Linux下python升级
  8. [x-means] 1.x-means简介
  9. Hibernate 系列教程3-单表操作
  10. AngularJS入门第一课
  11. 深入浅出Android之学习笔记
  12. java jdb 调试
  13. BZOJ5475 WC2019数树(prufer+容斥原理+树形dp+多项式exp)
  14. DBS:CUPhone
  15. Arrays.asList中所遇到的坑
  16. Mybatis将结果放入map时别名不是驼峰形式
  17. 程序员应该懂的ip地址知识汇总
  18. 文档比较比对工具Beyond Compare
  19. yarn 用户导致的被挖矿 启用Kerberos认证功能,禁止匿名访问修改8088端口
  20. s3c6410下移植sqlite3.7.8

热门文章

  1. AcWing 8.二维费用的背包问题
  2. Python的深拷贝、浅拷贝
  3. IDEA中进行远程调试springboot项目
  4. HTML5圆形百分比进度条插件circleChart
  5. zabbix-server报错:No route to host
  6. scrapy下载 大文件处理
  7. 【读书笔记】--《编写高质量iOS与OS X代码的52个有效方法》
  8. dk7和jdk8的一些新特性
  9. Python学习之函数篇
  10. EntityFramework 插入自增ID主从表数据