传送门
题意:
给一棵带点权的树,要求支持如下操作:
- 询问从 U 出发的简单路径,经过的点权值之和的最大值
- 将 U 的权值修改为 V
空间限制64MB
思路:
你可以使用一种叫做点分树的无脑方法,然后用 s h o r t + c h a r short+char short+char拼 3 4 \frac34 43个 i n t int int可以通过这一道题。 毕竟毒瘤出题人卡了空间
你显然也可以上 l c t lct lct搞。博主懒癌晚期不想写/想了
实在不行的就学博主大力链分治吧。
这跟那个 Q T R E E QTREE QTREE系列是一个套路,对于每条链用可删堆维护子树的信息,用线段树维护重链的信息,然后每次像上面跳即可。
注意这个时候查最大值直接跳可能会走到重复的点,因此查询的时候要先消除当前节点所在子树的影响才行。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
inline int read(){
int ans=0;
bool f=1;
char ch=getchar();
while(!isdigit(ch))f^=ch=='-',ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return f?ans:-ans;
}
typedef long long ll;
const int N=1e5+5,inf=0x3f3f3f3f;
int n,pred[N],num[N],tot=0,m,a[N],dep[N],top[N],fa[N],hson[N],siz[N],bot[N];
vector<int>e[N];
void dfs1(int p){
siz[p]=1;
for(ri i=0,v;i<e[p].size();++i