dsu on tree(無講解)
阿新 • • 發佈:2018-11-25
stdout lin i++ pri scanf || sca n) names
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); }
dsu on tree(無講解)