社区讨论
树剖2点TLE。。有问题吗
P2590[ZJOI2008] 树的统计参与者 4已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mi6x81sy
- 此快照首次捕获于
- 2025/11/20 12:18 4 个月前
- 此快照最后确认于
- 2025/11/20 12:18 4 个月前
8个点都对的,剩下2个点就是跑不过去,自己生成数据也超时,就是调不出来,这代码大致思路应该没问题吧。。QwQ
CPP#include<bits/stdc++.h>
#define l (i<<1)
#define r (i<<1|1)
#define mid ((L+R)>>1)
using namespace std;
const int N=30000+7;
const int INF=0x3f3f3f3f;
inline int read(){
int x=0,f=0;char c;
while(!isdigit(c=getchar()))if(c=='-')f=1;
while(isdigit(c))x=(x<<3)+(x<<1)+(c^'0'),c=getchar();
return f?-x:x;
}
inline int _max(int a,int b){return a<b?b:a;}
int sumv[N<<4],maxv[N<<4],tag[N<<4];
int v[N<<1],Next[N<<1],Head[N],val[N],fa[N],son[N],depth[N],cnt[N],pos[N],A[N],topf[N];
char s[10];
int n,x,y,tot,q,tmp;
inline void Addedge(){
v[++tot]=y,Next[tot]=Head[x],Head[x]=tot,v[++tot]=x,Next[tot]=Head[y],Head[y]=tot;
}
void dfs1(int u,int f){
cnt[u]=1,fa[u]=f,tmp=-1;
for(register int j=Head[u];j;j=Next[j]){
int y=v[j];if(y==f) continue;
depth[y]=depth[u]+1,dfs1(y,u),cnt[u]+=cnt[y];
if(tmp<cnt[y]) tmp=cnt[y],son[u]=y;
}
}
void dfs2(int u,int topfa){
pos[u]=++tot,A[tot]=val[u],topf[u]=topfa;
if(!son[u]) return;
dfs2(son[u],topfa);
for(register int j=Head[u];j;j=Next[j]) if(v[j]!=fa[u]&&v[j]!=son[u]) dfs2(v[j],v[j]);
}
void build(int i,int L,int R){
if(L==R){maxv[i]=sumv[i]=A[L];return;}
build(l,L,mid),build(r,mid+1,R),maxv[i]=_max(maxv[l],maxv[r]),sumv[i]=sumv[l]+sumv[r];
}
void Update(int i,int L,int R){
if(L==R){maxv[i]=sumv[i]=y;return;}
if(x<=mid) Update(l,L,mid);else Update(r,mid+1,R);
sumv[i]=sumv[l]+sumv[r],maxv[i]=_max(maxv[l],maxv[r]);
}
int Query_max(int i,int L,int R,int ql,int qr){
if(ql<=L&&qr>=R) return maxv[i];
int ret=-INF;
if(ql<=mid) ret=_max(ret,Query_max(l,L,mid,ql,qr));
if(qr>mid) ret=_max(ret,Query_max(r,mid+1,R,ql,qr));
return ret;
}
int Query_sum(int i,int L,int R,int ql,int qr){
if(ql<=L&&qr>=R) return sumv[i];
int ret=0;
if(ql<=mid) ret+=Query_sum(l,L,mid,ql,qr);
if(qr>mid) ret+=Query_sum(r,mid+1,R,ql,qr);
return ret;
}
int Qmax(){
int ret=-INF;
while(topf[x]!=topf[y]){
if(depth[topf[x]]<depth[topf[y]]) x^=y^=x^=y;
ret=_max(ret,Query_max(1,1,n,pos[topf[x]],pos[x]));
x=fa[topf[x]];//cerr<<ret<<endl;
}
if(depth[x]>depth[y]) x^=y^=x^=y;//cerr<<x<<" "<<pos[x]<<" "<<y<<" "<<pos[y]<<endl;
return _max(ret,Query_max(1,1,n,pos[x],pos[y]));
}
int Qsum(){
int ret=0;
while(topf[x]!=topf[y]){
if(depth[topf[x]]<depth[topf[y]]) x^=y^=x^=y;
ret+=Query_sum(1,1,n,pos[topf[x]],pos[x]);
x=fa[topf[x]];
}
if(depth[x]>depth[y]) x^=y^=x^=y;
return ret+Query_sum(1,1,n,pos[x],pos[y]);
}
int main(){//freopen("tmp.txt","r",stdin);freopen("ans.txt","w",stdout);
n=read();
for(register int i=1;i<n;++i) x=read(),y=read(),Addedge();
for(register int i=1;i<=n;++i) val[i]=read();
tot=0,depth[1]=1,dfs1(1,0),dfs2(1,1),build(1,1,n),q=read();
for(register int i=1;i<=q;++i){
scanf("%s",s);x=read(),y=read();
if(s[1]=='H') x=pos[x],Update(1,1,n);
else if(s[1]=='M') printf("%d\n",Qmax());
else printf("%d\n",Qsum());
}
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...