求调点分树,TLE+MLE 0pts
查看原帖
求调点分树,TLE+MLE 0pts
681036
OldDriverTree楼主2024/3/2 16:36

rt,样例能过,link

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
vector<int> g[N],G[N];
int root,siz[N],fa[N];
int n,m,a[N],Fa[N];
int top[N],dep[N];
bool del[N];

int read() {
	int x=0; char c=0; while (!isdigit(c) ) c=getchar();
	while (isdigit(c) ) x=(x<<3)+(x<<1)+(c&15),c=getchar();
	return x;
}
struct BIT {
	vector<int> T;
	void add(int x,int y) { while (x<T.size() ) T[x]+=y,x+=x&-x; }
	int query(int x,int sum=0) { while (x) sum+=T[x],x&=x-1; return sum; }
}A[N],B[N];

void dfs1(int u) {
	dep[u]=dep[Fa[u] ]+1,siz[u]=1;
	for (int v:g[u]) if (v^Fa[u]) Fa[v]=u,dfs1(v),siz[u]+=siz[v];
}
void dfs2(int u)
{
	int son=0;
	for (int v:g[u])
		if (v^Fa[u]&&siz[v]>siz[son])
			son=v;
	
	if (son) top[son]=top[u],dfs2(son);
	for (int v:g[u]) if (v^Fa[u]&&v^son) top[v]=v,dfs2(v);
}
int dis(int x,int y)
{
	int u=x,v=y;
	while (top[x]^top[y]) {
		if (dep[top[x] ]<dep[top[y] ]) swap(x,y);
		x=Fa[top[x] ];
	}
	int LCA=dep[x]<dep[y]?x:y;
	return dep[u]+dep[v]-dep[LCA]*2;
}
void get_size(int u,int fa) {
	siz[u]=1; for (int v:g[u]) if (v^fa&&!del[v])
	get_size(v,u),siz[u]+=siz[v];
}
void get_root(int u,int fa,int Siz,int &rt)
{
	int sz=Siz-siz[u];
	for (int v:g[u]) if (v^fa&&!del[v])
	get_root(v,u,Siz,rt),sz=max(sz,siz[v]);
	if (sz<=Siz/2) rt=u;
}
int build(int u) {
	get_size(u,0),get_root(u,0,siz[u],u),del[u]=true;
	for (int v:g[u]) if (!del[v]) G[u].push_back(build(v) ); return u;
}
void dfs(int u) {
	siz[u]=1; for (int v:G[u])
	fa[v]=u,dfs(v),siz[u]+=siz[v];
}
void change(int x,int w)
{
	int u=x;
	A[u].add(1,w);
	while (fa[u]) {
		int t=dis(x,fa[u])+1;
		A[fa[u] ].add(t,w);
		B[u].add(t,w),u=fa[u];
	}
}
int query(int x,int k)
{
	int u=x,ans=A[u].query(min(siz[u],k+1) );
	while (fa[u]) {
		int t=dis(fa[u],x); if (t>k) continue;
		ans+=A[fa[u] ].query(min(siz[fa[u] ],k-t+1) );
		ans-=B[u].query(min(siz[fa[u] ],k-t+1) ),u=fa[u];
	}
	return ans;
}
int main()
{
	n=read(),m=read();
	for (int i=1;i<=n;i++) a[i]=read();
	for (int i=1,x,y;i<n;i++) x=read(),y=read(),
	g[x].push_back(y),g[y].push_back(x);
	dfs1(1),top[1]=1,dfs2(1);
	dfs(root=build(1) ); int last=0;
	for (int i=1;i<=n;i++) A[i].T.resize(siz[i]+1),B[i].T.resize(siz[fa[i] ]+1);
	for (int i=1;i<=n;i++) change(i,a[i]);
	while (m--) {
		int o=read(),x=read()^last,y=read()^last;
		if (o) change(x,y-a[x]),a[x]=y;
		else printf("%d\n",last=query(x,y) );
	}
	return 0;
}
2024/3/2 16:36
加载中...