回滚莫队+01trie 0pts wa&mle
查看原帖
回滚莫队+01trie 0pts wa&mle
536743
arrow_king楼主2024/5/25 19:23

rt.自己看了半天没找到错,大佬帮帮吧……

record

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
#define il inline
#define MAXH 31
#define N 30005
#define int long long
#define bl(x) ((x+sqr-1)/sqr)
il ll read() {
	ll x=0,f=1;char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') {f=-1;} c=getchar();}
	while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}
struct node {
	int ch[2],w;
};
node trie[N*31*20];
int n,a[2*N],root,tot,dfn[N],tim,siz[N];
int sqr,ans[N],tmp;
vector<pair<int,int> > g[N];
il void dfs(int u,int fa) {
	siz[u]=1;
	for(auto p:g[u]) {
		int v=p.first,w=p.second;
		if(v==fa) continue;
		dfn[v]=++tim;
		a[dfn[v]]=a[dfn[u]]^w;
		dfs(v,u);
		siz[u]+=siz[v];
	}
}
il int newnode() {
	++tot;
	trie[tot].ch[0]=trie[tot].ch[1]=trie[tot].w=0;return tot;
}
il void insert(int x) {
	if(!root) root=newnode();int u=root;trie[root].w++;
	for(int i=MAXH,way=(x>>MAXH)&1;i>=0;i--,way=(x>>i)&1) {
		if(!trie[u].ch[way]) trie[u].ch[way]=newnode();
		trie[trie[u].ch[way]].w++;
		u=trie[u].ch[way];
	}
}
il void del(int x) {
	int u=root;trie[root].w--;if(trie[root].w==0) return (void)(root=0);
	for(int i=MAXH,way=(x>>MAXH)&1;i>=0;i--,way=(x>>i)&1) {
		trie[trie[u].ch[way]].w--;
		if(trie[trie[u].ch[way]].w==0) return (void)(trie[u].ch[way]=0);
		u=trie[u].ch[way];
	}
}
il void add(int x) {
	if(!root) {return insert(x);}
	int u=root,ans=0;
	for(int i=MAXH,way=(x>>MAXH)&1;i>=0;i--,way=(x>>i)&1) {
		if(trie[u].ch[way^1]) ans+=(1ll<<i),u=trie[u].ch[way^1];
		else u=trie[u].ch[way];
	}
	insert(x);tmp=max(tmp,ans);
}
struct query {
	int l,r,id;
	query() {l=r=id=0;}
	query(int _l,int _r,int _id) {l=_l,r=_r,id=_id;}
};
query q[N*2];
il bool cmp(query q1,query q2) {
	if(bl(q1.l)!=bl(q2.l)) return bl(q1.l)<bl(q2.l);
	return q1.r<q2.r;
}
signed main() {
	n=read(),sqr=max(1.0,sqrt(n)*0.66);
	for(int i=1;i<n;i++) {
		int u=read(),v=read(),w=read();
		g[u].push_back(make_pair(v,w));
		g[v].push_back(make_pair(u,w));
	}
	dfn[1]=tim=1;
	dfs(1,0);
	for(int i=1;i<=n;i++) a[i+n]=a[i];
	for(int i=1;i<=n;i++) {
		q[2*i-1]=query(dfn[i],dfn[i]+siz[i]-1,2*i-1);
		q[2*i]=query(dfn[i]+siz[i],dfn[i]+n-1,2*i);
	}
	sort(q+1,q+2*n+1,cmp);
	int r=bl(q[1].l)*sqr,l=r+1;
	for(int i=1;i<=2*n;i++) {
		if(bl(q[i].l)>=bl(l)) {
			tmp=0;
			for(int j=r;j>=l;j--) del(a[j]);
			r=bl(q[i].l)*sqr,l=r+1;
		}
		if(bl(q[i].l)==bl(q[i].r)) {
			for(int j=q[i].l;j<=q[i].r;j++) add(a[j]);
			ans[q[i].id]=tmp;
			for(int j=q[i].l;j<=q[i].r;j++) del(a[j]);
			tmp=0;
		}
		while(r<q[i].r) add(a[++r]);
		int mv=tmp;
		for(int j=q[i].l;j<l;j++) add(a[j]);
		ans[q[i].id]=tmp;
		for(int j=q[i].l;j<l;j++) del(a[j]);
		tmp=mv;
	}
	/*for(int i=1;i<=n;i++) printf("%d ",dfn[i]);putchar('\n');
	for(int i=1;i<=2*n;i++) printf("%d ",a[i]);
	putchar('\n');
	for(int i=1;i<=2*n;i++) {
		printf("query %d: from %d to %d,ans=%d\n",q[i].id,q[i].l,q[i].r,ans[i]);
	}*/
	ll final=0;
	for(int i=2;i<=n;i++) final=max(final,1ll*ans[2*i-1]+ans[2*i]);
	printf("%lld\n",final);
	return 0;
}
2024/5/25 19:23
加载中...