社区讨论

树剖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 条回复,欢迎继续交流。

正在加载回复...