社区讨论
淀粉熟全T求助
P6329【模板】点分树 / 震波参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lyh9kwtp
- 此快照首次捕获于
- 2024/07/11 20:47 2 年前
- 此快照最后确认于
- 2024/07/11 20:51 2 年前
只看淀粉质部分即可
CPP#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <set>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int ll
#define lowbit(x) x&(-x)
int read()
{
ll now = 0, nev = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
nev = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
now = (now << 1) + (now << 3) + (c & 15);
c = getchar();
}
return now * nev;
}
const int MAXN = 1e6 + 10;
const int mod = 998244353;
int n,m;
int a[MAXN];
int head[MAXN],tt=0;
struct edge
{
int to,nxt,dis;
}e[MAXN<<1];
void add(int x,int y)
{
e[++tt].nxt=head[x];
head[x]=tt;
e[tt].to=y;
e[tt].dis=1;
}
int fa[MAXN],siz[MAXN],son[MAXN],dep[MAXN];
int top[MAXN];
void dfs1(int u,int fat)
{
fa[u]=fat;
dep[u]=dep[fat]+1;
siz[u]=1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fat)
continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v])
son[u]=v;
}
}
void dfs2(int u,int topfa)
{
top[u]=topfa;
if(son[u])
dfs2(son[u],topfa);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa[u] || v==son[u])
continue;
dfs2(v,v);
}
}
int LCA(int x,int y)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]])
swap(x, y);
x = fa[top[x]];
}
if (dep[x]>dep[y])
swap(x, y);
return x;
}
int dis(int x,int y)
{
return dep[x]+dep[y]-2*dep[LCA(x,y)];
}
struct BIT
{
vector<int>bit;
void build(int sz)
{
for(int i=0;i<=sz+3;i++)
bit.push_back(0);
}
void add(int x,int v)
{
while(x<=bit.size())
{
bit[x]+=v;
x+=lowbit(x);
}
}
int ask(int x)
{
x=min(x,(int)bit.size()-1);
int res=0;
while(x)
{
res+=bit[x];
x-=lowbit(x);
}
return res;
}
}s1[MAXN],s2[MAXN];
bool vis[MAXN];
void dfs3(int rt,int u,int fat,int len)
{
s1[rt].add(len,a[u]);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fat || vis[v])
continue;
dfs3(rt,v,u,len+1);
}
}
int seg[MAXN],idx=0;
int f[MAXN];
void dfs4(int u,int fat)
{
seg[++idx]=u;
siz[u]=1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fat ||vis[v])
continue;
dfs4(v,u);
siz[u]+=siz[v];
f[u]=max(f[u],siz[v]);
}
}
void init(int u,int fat)
{
idx=0;
dfs4(u,0);
for(int i=1;i<=idx;i++)
f[seg[i]]=max(f[seg[i]],idx-siz[seg[i]]);
int rt=-1;
for(int i=1;i<=idx;i++)
{
if(rt==-1 || f[rt]>f[seg[i]])
rt=seg[i];
}
for(int i=1;i<=idx;i++)
f[seg[i]]=0;
vis[rt]=1;
u=rt;
fa[u]=fat;
s2[u].build(idx);
if(fat)
{
for(int i=1;i<=idx;i++)
s2[u].add(dis(seg[i],fat),a[seg[i]]);
}
s1[u].build(idx);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(vis[v])
continue;
dfs3(u,v,u,1);
}
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(vis[v])
continue;
init(v,u);
}
}
void modefy(int x,int v)
{
int u=x;
while(fa[u])
{
int d=dis(x,fa[u]);
s2[u].add(d,-a[x]);
s2[u].add(d,v);
u=fa[u];
s1[u].add(d,-a[x]);
s1[u].add(d,v);
}
a[x]=v;
}
int query(int x,int v)
{
int res=0;
int u=x;
res+=a[x]+s1[x].ask(v);
while(fa[u])
{
int d=dis(x,fa[u]);
if(d<=v)
res+=a[fa[u]]+s1[fa[u]].ask(v-d)-s2[u].ask(v-d);
u=fa[u];
}
return res;
}
signed main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
add(x,y),add(y,x);
}
dfs1(1,0),dfs2(1,0);
init(1,0);
int ans=0;
for(int i=1;i<=m;i++)
{
int op=read(),x=read(),y=read();
x^=ans,y^=ans;
if(op==0)
printf("%lld\n",ans=query(x,y));
if(op==1)
modefy(x,y);
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...