dsu on tree(无讲解)

CF741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

分析:

  • 最多有一个字符出现奇数次
  • 维护某个状态下深度的最大值,注意是全局深度
  • 写成非递归形式方便理解

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 500050
#define M (1<<22)
#define inf 0x3f3f3f3f
int head[N],to[N<<1],nxt[N<<1],cnt,n,val[N<<1];
int mx[M],siz[N],ans[N],son[N];
int dfn[N],idf[N],enp[N];
int nowans,dep[N],len[N];
inline void add(int u,int v,int w) {
	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
}
void df1(int x,int y) {
	int i;
	siz[x]=1; len[x]=len[y]+1;
	dfn[x]=++dfn[0]; idf[dfn[0]]=x;
	for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
		dep[to[i]]=dep[x]^(1<<val[i]);
		df1(to[i],x);
		siz[x]+=siz[to[i]];
		if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
	}
	enp[x]=dfn[0];
}
void df2(int x,int y,int opt) {
	int i;
	for(i=head[x];i;i=nxt[i]) if(to[i]!=y&&to[i]!=son[x]) {
		df2(to[i],x,0); ans[x]=max(ans[x],ans[to[i]]);
	}
	if(son[x]) {
		df2(son[x],x,1);
		ans[x]=max(ans[x],ans[son[x]]);
		nowans=max(nowans,mx[dep[x]]-len[x]);
		for(i=0;i<22;i++) nowans=max(nowans,mx[dep[x]^(1<<i)]-len[x]);
	}
	mx[dep[x]]=max(mx[dep[x]],len[x]);
	for(i=head[x];i;i=nxt[i]) if(to[i]!=y&&to[i]!=son[x]) {
		int t=to[i],j,p,k;
		for(j=dfn[t];j<=enp[t];j++) {
			p=idf[j];
			nowans=max(nowans,mx[dep[p]]+len[p]-len[x]*2);
			for(k=0;k<22;k++) nowans=max(nowans,mx[ dep[p]^(1<<k) ]+len[p]-len[x]*2);
		}
		for(j=dfn[t];j<=enp[t];j++) {
			p=idf[j];
			mx[dep[p]]=max(mx[dep[p]],len[p]);
		}
	}
	ans[x]=max(ans[x],nowans);
	if(!opt) {
		nowans=-inf;
		for(i=dfn[x];i<=enp[x];i++) mx[dep[idf[i]]]=-inf;
	}
}
int main() {
	memset(mx,0xc0,sizeof(mx));
	scanf("%d",&n);
	int i,x; 
	char op[4];
	for(i=2;i<=n;i++) {
		scanf("%d%s",&x,op);
		add(x,i,op[0]-'a'); add(i,x,op[0]-'a');
	}
	df1(1,0);
	df2(1,0,1);
	for(i=1;i<=n;i++) printf("%d ",ans[i]);
}

BZOJ5457: 城市

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 400050
int head[N],to[N<<1],nxt[N<<1],n,m,cnt;
int a[N],b[N],dfn[N],idf[N],fa[N],enp[N],son[N],siz[N],top[N];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
char buf[100000],*p1,*p2;
inline int rd() {
	int x=0;char c=nc();
	while(c<48)c=nc();
	while(c>47)x=((x+(x<<2))<<1)+(c^48),c=nc();
	return x;
}
inline void add(int u,int v) {
	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void df1(int x,int y) {
	int i; fa[x]=y;
	siz[x]=1; dfn[x]=++dfn[0]; idf[dfn[0]]=x;
	for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
		df1(to[i],x);
		siz[x]+=siz[to[i]];
		if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
	}
	enp[x]=dfn[0];
}
int nowans,ans[N],c[N],tot[N];
void df2(int x) {
	int i,j,t,lim;
	for(i=head[x];i;i=nxt[i]) if(to[i]!=son[x]&&to[i]!=fa[x]) {
		df2(to[i]);
	}
	if(son[x]) df2(son[x]);
	c[a[x]]+=b[x];
	if(c[nowans]<c[a[x]]||(c[nowans]==c[a[x]]&&nowans>a[x])) {
		nowans=a[x];
	}
	for(i=head[x];i;i=nxt[i]) if(to[i]!=son[x]&&to[i]!=fa[x]) {
		t=to[i],lim=enp[t];
		for(j=dfn[t];j<=lim;j++) {
			int p=idf[j];
			c[a[p]]+=b[p];
	if(c[nowans]<c[a[p]]||(c[nowans]==c[a[p]]&&nowans>a[p])) {
		nowans=a[p];
	}
		}
	}
	ans[x]=nowans; tot[x]=c[nowans];
	if(son[fa[x]]!=x) {nowans=0;for(lim=enp[x],i=dfn[x];i<=lim;i++) c[a[idf[i]]]=0;}
}
char pbuf[4000000],*pp=pbuf;
int sta[30],tp;
void write(int x) {
	if(x<0) *pp++='-',x=-x;
	do {sta[++tp]=x%10,x/=10;}while(x);
	while(tp)*pp++=sta[tp--]+'0';
}
int main() {
	n=rd(),m=rd();
	int i,x,y;
	for(i=1;i<n;i++) x=rd(),y=rd(),add(x,y),add(y,x);
	for(i=1;i<=n;i++) a[i]=rd(),b[i]=rd();
	df1(1,0); df2(son[0]=1);
	for(i=1;i<=n;i++) {
		write(ans[i]); *pp++=' '; write(tot[i]); *pp++='\n';
	}
	fwrite(pbuf,1,pp-pbuf,stdout);
}

posted @ 2018-11-25 13:21  fcwww  阅读(187)  评论(0编辑  收藏  举报