社区讨论
学oi一年了 男孩子 以及这个树剖莫名其妙炸了
P2590[ZJOI2008] 树的统计参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mi7cnui5
- 此快照首次捕获于
- 2025/11/20 19:30 4 个月前
- 此快照最后确认于
- 2025/11/20 19:30 4 个月前
CPP
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#define il inline
#define f(i,a,n) for(register int i=a;i<=n;++i)
#define mid ((l+r)>>1)
#define v e[i].to
#define lson fl(p),l,mid
#define rson fr(p),mid+1,r
using namespace std;
il int fl(int x) {return x<<1;}
il int fr(int x) {return x<<1|1;}
il int lb(int x) {return x&(-x);}
il int re()
{
int res=0,b=1;char c=getchar();
while(('0'>c||c>'9')&&c!='-') c=getchar();
if(c=='-') b=-b,c=getchar();
while(c>='0'&&c<='9') res=(res<<1)+(res<<3)+c-'0',c=getchar();
return res*b;
}
int siz[30500],son[30500],dep[30500],fa[30500];
int id[30500],top[30500],tot;
int zkw,tree[60500],mx[60500];
int head[30500],cnt;
int n,m;
char use[60];
struct edge{int fa,to;}e[60500];
void addedge(int a,int b)
{
e[++cnt].fa=head[a];
e[cnt].to=b;
head[a]=cnt;
}
void dfs(int u,int f)
{
dep[u]=dep[f]+1;
fa[u]=f;
siz[u]=1;
int maxson=-1;
for(int i=head[u];i;i=e[i].fa)
{
if(v==f) continue;
dfs(v,u);
siz[u]+=siz[v];
if(maxson<siz[v]) maxson=siz[v],son[u]=v;
}
}
void dfs2(int u,int root)
{
top[u]=root;
id[u]=++tot;
if(!son[u]) return;
dfs2(son[u],root);
for(int i=head[u];i;i=e[i].fa)
{
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
void change(int p,int n)
{
int a=p+zkw;
tree[a]=n,mx[a]=n;
for(a>>=1;a;a>>=1)
tree[a]=tree[fl(a)]+tree[fr(a)];
mx[a]=max(mx[fl(a)],mx[fr(a)]);
}
int askmx(int l,int r)
{
int res=-19260817;
for(int s=l+zkw-1,t=r+zkw+1;s^t^1;s>>=1,t>>=1)
{
if(~s&1) res=max(res,mx[s^1]);
if(t&1) res=max(res,mx[t^1]);
}
return res;
}
int asknum(int l,int r)
{
int res=0;
for(int s=l+zkw-1,t=r+zkw+1;s^t^1;s>>=1,t>>=1)
{
if(~s&1) res+=tree[s^1];
if(t&1) res+=tree[t^1];
}
return res;
}
void setup()
{
n=re();
for(zkw=1;zkw<=n+1;zkw<<=1);
f(i,1,n-1)
{
int a=re(),b=re();
addedge(a,b);
addedge(b,a);
}
dfs(1,0);
dfs2(1,1);
f(i,zkw+n+1,zkw+zkw-1) mx[i]=-192608;
f(i,1,n)
{
int c=re();
tree[id[i]+zkw]=c;
mx[id[i]+zkw]=c;
}
for(int i=zkw-1;i>=1;i--)
tree[i]=tree[fl(i)]+tree[fr(i)],
mx[i]=max(mx[fl(i)],mx[fr(i)]);
m=re();
}
int sum(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=asknum(id[top[x]],id[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=asknum(id[x],id[y]);
return ans;
}
int maxnum(int x,int y)
{
int ans=-192608;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,askmx(id[top[x]],id[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans=max(ans,askmx(id[x],id[y]));
return ans;
}
int main()
{
setup();
f(j,1,m)
{
int x,y;
scanf("%s%d%d",use,&x,&y);
if(use[0]=='C') change(id[x],y);
else
{
if(use[1]=='M') printf("%d\n",maxnum(x,y));
else printf("%d\n",sum(x,y));
}
}
return 0;
}
大佬求教啊,不想noip前这个树剖炸掉啊(QAQ)
回复
共 3 条回复,欢迎继续交流。
正在加载回复...