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);
}


猜你喜欢

转载自www.cnblogs.com/suika/p/10015361.html