【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

题意:我们称一个字符串为周驿东串当且仅当重排它的字符可以组成一个回文串。

给出一个n个点的有根树,根为1,每条边上有一个从a到v的字符,求每个点的子树中所有简单路径可以组成的周驿东串中的最长长度。

n<=5e5

思路:https://www.cnblogs.com/zzqsblog/p/6146916.html

一个串为周驿东串当且仅当其中只有0/1个字符出现奇数次

将每个字母看成一个二进制位,设s[i]为根到i的边权xor和,对于固定的点x要在其子树中找到来自不同分支的a和b使得s[a]^s[b]为0或者2的次幂,且dep[a]+dep[b]-2*dep[x]最大

s[a]^s[b]的条件等价于s[a]=s[b]或者s[a]和s[b]只有1位不同

lca直接当做x算实际上的dep应该比算dep[x]大,答案会变大,需要先统计再更新

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 typedef pair<ll,int>P;
 11 #define N  500010
 12 #define M  1000010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pi acos(-1)
 17 #define mem(a,b) memset(a,b,sizeof(a))
 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 20 #define lowbit(x) x&(-x)
 21 #define Rand (rand()*(1<<16)+rand())
 22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 23 #define ls p<<1
 24 #define rs p<<1|1
 25 #define S 1<<22
 26 
 27 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 28       double eps=1e-6;
 29       int INF=1<<30;
 30       ll inf=5e13;
 31       int dx[4]={-1,1,0,0};
 32       int dy[4]={0,0,-1,1};
 33 
 34 char ch[10];
 35 int head[N],vet[M],nxt[M],len[M],tot;
 36 int son[N],dep[N],s[N],size[N],skip;
 37 int ans[N],mxdep[1<<23],now,t;
 38 
 39 int read()
 40 {
 41    int v=0,f=1;
 42    char c=getchar();
 43    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 44    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 45    return v*f;
 46 }
 47 
 48 void add(int a,int b,int c)
 49 {
 50     nxt[++tot]=head[a];
 51     vet[tot]=b;
 52     len[tot]=c;
 53     head[a]=tot;
 54 }
 55 
 56 void dfs1(int u,int fa)
 57 {
 58     size[u]=1;
 59     int e=head[u];
 60     while(e)
 61     {
 62         int v=vet[e];
 63         if(v!=fa)
 64         {
 65             dep[v]=dep[u]+1;
 66             s[v]=s[u]^len[e];
 67             dfs1(v,u);
 68             size[u]+=size[v];
 69             if(size[v]>size[son[u]]) son[u]=v;
 70         }
 71         e=nxt[e];
 72     }
 73 }
 74 
 75 void clr(int u)
 76 {
 77     mxdep[s[u]]=-INF;
 78 }
 79 
 80 void update(int u)
 81 {
 82     t=max(t,mxdep[s[u]]+dep[u]-now*2);
 83     rep(i,0,21) t=max(t,mxdep[s[u]^(1<<i)]+dep[u]-now*2);
 84 }
 85 
 86 void ins(int u)
 87 {
 88     mxdep[s[u]]=max(mxdep[s[u]],dep[u]);
 89 }
 90 
 91 void solve(int u,int fa,int op)
 92 {
 93     if(op==0) clr(u);
 94     if(op==1) update(u);
 95     if(op==2) ins(u);
 96     int e=head[u];
 97     while(e)
 98     {
 99         int v=vet[e];
100         if(v!=fa&&v!=skip) solve(v,u,op);
101         e=nxt[e];
102     }
103 }
104 
105 void dfs2(int u,int fa,int op)
106 {
107     int e=head[u];
108     while(e)
109     {
110         int v=vet[e];
111         if(v!=fa&&v!=son[u]) dfs2(v,u,0);
112         e=nxt[e];
113     }
114     if(son[u])
115     {
116         dfs2(son[u],u,1);
117         skip=son[u];
118     }
119     now=dep[u];
120     e=head[u];
121     while(e)
122     {
123         int v=vet[e];
124         if(v!=fa) ans[u]=max(ans[u],ans[v]);
125         e=nxt[e];
126     }
127     e=head[u];
128     while(e)
129     {
130         int v=vet[e];
131         if(v!=fa&&v!=son[u])
132         {
133             solve(v,u,1);
134             solve(v,u,2);
135         }
136         e=nxt[e];
137     }
138     update(u);
139     ins(u);
140     ans[u]=max(ans[u],t);
141     skip=0;
142     if(!op)
143     {
144         solve(u,fa,0);
145         t=-INF;
146     }
147 }
148 
149 int main()
150 {
151     //freopen("1.in","r",stdin);
152     //freopen("1.out","w",stdout);
153 
154     rep(i,0,S) mxdep[i]=-INF;
155     int n=read();
156     tot=0;
157     rep(i,2,n)
158     {
159         int x;
160         scanf("%d%s",&x,ch);
161         add(x,i,1<<(ch[0]-'a'));
162         add(i,x,1<<(ch[0]-'a'));
163     }
164     skip=t=now=0;
165     dfs1(1,0);
166     dfs2(1,0,0);
167     rep(i,1,n) printf("%d ",ans[i]);
168     return 0;
169 }

 

posted on 2019-09-19 19:23  myx12345  阅读(179)  评论(0编辑  收藏  举报

导航