社区讨论

正确复杂度TLE求优化

P5556 圣剑护符参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lo11e8r9
此快照首次捕获于
2023/10/22 13:37
2 年前
此快照最后确认于
2023/11/02 11:55
2 年前
查看原帖
AC+TLE,谢谢众大佬
CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=100009; 
ll n,q,v[N],son[N],top[N],tI[N],id[N],timer=0,d[N],p[N],sz[N],C[N];
vector<ll> to[N];
struct edge{ll l,r,toXor;}tr[4*N];
void buildST(ll x,ll l,ll r){
	tr[x]=(edge){l,r,0};
	if(l==r){tr[x].toXor=v[tI[l]];return;}////
	ll mid=l+(r-l)/2;
	buildST(x*2,l,mid);
	buildST(x*2+1,mid+1,r);
}
void add(ll x,ll l,ll r,ll z){
//	if(x==1) cout<<l<<"~"<<r<<":"<<z<<"\n"; 
	if(tr[x].l>r||tr[x].r<l) return;
	if(l<=tr[x].l&&tr[x].r<=r){tr[x].toXor^=z;return;}
	add(x*2,l,r,z);
	add(x*2+1,l,r,z);
}
ll query(ll x,ll i){
	if(tr[x].l==tr[x].r) return tr[x].toXor;
	return tr[x].toXor^(i<=tr[x*2].r?query(x*2,i):query(x*2+1,i));
}
void dfs2(ll x,ll fa){
	if(son[fa]==x) top[x]=top[fa];
	else top[x]=x;
	tI[id[x]=++timer]=x;//id[i]:节点->线段树
						//tI[i]:线段树->节点
	if(son[x]) dfs2(son[x],x);
	for(ll i=0,v;i<to[x].size();++i)
		if((v=to[x][i])^fa&&v^son[x])
			dfs2(v,x);
}
void dfs1(ll x,ll fa){
	p[x]=fa,d[x]=d[fa]+1,sz[x]=1;
	for(ll i=0,v;i<to[x].size();++i)
		if((v=to[x][i])^fa){
			dfs1(v,x);
			sz[x]+=sz[v];
			if(sz[v]>sz[son[x]]) son[x]=v;
		}
}
ll lca(ll x,ll y){
	while(top[x]^top[y]){
		ll &a=(d[top[x]]>d[top[y]]?x:y);
		a=p[top[a]];
	}
	return (d[x]<d[y]?x:y);
}
bool jiAdd(ll a){
//	cout<<"jiAdd:"<<a<<"\n";
	if(a==0) return 1;//// 
	for(ll i=30;i>=0;--i)
		if(a&(1<<i)){
			if(C[i]) a^=C[i];
			else{C[i]=a;return 0;}
		}
	return 1;
}
bool Q(ll x,ll y){
	ll l=lca(x,y);
	if(d[x]+d[y]-2*d[l]+1>=32) return 1;
//	cout<<"Q:"<<x<<" "<<y<<" "<<l<<"\n";
	memset(C,0,sizeof(C));
	while(1){
		if(jiAdd(query(1,id[x]))) return 1;
		if(x==l) break;
		x=p[x];
	}
	while(1){
		if(y==l) break;
		if(jiAdd(query(1,id[y]))) return 1;
		y=p[y];
	}
	return 0;
}
void adlian(ll x,ll fa,ll v){
	while(d[top[x]]>=d[fa]){
		add(1,id[top[x]],id[x],v),
		x=p[top[x]];
	}
	if(d[x]>=d[fa]) add(1,id[fa],id[x],v);
}
void upd(ll x,ll y,ll v){
	ll l=lca(x,y);
	adlian(x,l,v);
	adlian(y,l,v);
	add(1,id[l],id[l],v);////
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	cin>>n>>q;
	for(ll i=1;i<=n;++i) cin>>v[i];
	for(ll i=1;i<n;++i){
		ll x,y;
		cin>>x>>y;
		to[x].push_back(y);
		to[y].push_back(x);
	}
	dfs1(1,0);
	dfs2(1,0);
	buildST(1,1,n);
	for(ll i=1;i<=q;++i){
		string op;
		cin>>op;
		if(op=="Update"){
			ll x,y,v;
			cin>>x>>y>>v;
			upd(x,y,v);
		}else{
			ll x,y;
			cin>>x>>y;
			if(Q(x,y)) cout<<"YES\n";
			else cout<<"NO\n";
		}
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...