zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    ubuntu网络配置相关知识(转载)
    git 冲突解决(转载)
    redmine后台运行命令
    CentOS配置网卡,重启网络显示:Device does not seem to be present(转载)
    解决Xshell和vim中文乱码(转载)
    REDHAT6.2配置yum源(64位)(转载)
    Doki Doki Literature Club ZOJ
    CONTINUE...? ZOJ
    Magic Points ZOJ
    Cash Machine (POJ 1276)(多重背包——二进制优化)
  • 原文地址:https://www.cnblogs.com/myx12345/p/11551914.html
Copyright © 2011-2022 走看看