zoukankan      html  css  js  c++  java
  • bzoj4199 [Noi2015]品酒大会

    题面:见uoj

    正解:后缀自动机+后缀树+树形$dp$。

    好像这题正解是后缀数组来着,然而用后缀自动机就简单多了。。

    反串构出后缀树,然后直接树形$dp$即可,注意最大答案可能是最小值与最小值的乘积。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define Inf (1000000007)
     6 #define inf (1LL<<60)
     7 #define N (600010)
     8 
     9 using namespace std;
    10 
    11 struct edge{ int nt,to; }g[N<<1];
    12 
    13 int ch[N][26],fa[N],l[N],sz[N],Mx[N],Mn[N],val[N],head[N],a[N],n,la,tot,len,num;
    14 ll sum[N],res[N];
    15 char s[N];
    16 
    17 il int gi(){
    18   RG int x=0,q=1; RG char ch=getchar();
    19   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    20   if (ch=='-') q=-1,ch=getchar();
    21   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    22   return q*x;
    23 }
    24 
    25 il void insert(RG int from,RG int to){
    26   g[++num]=(edge){head[from],to},head[from]=num; return;
    27 }
    28 
    29 il void add(RG int c){
    30   RG int p=la,np=++tot; la=np,l[np]=l[p]+1,sz[np]=1;
    31   for (;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
    32   if (!p){ fa[np]=1; return; } RG int q=ch[p][c];
    33   if (l[q]==l[p]+1) fa[np]=q; else{
    34     RG int nq=++tot; l[nq]=l[p]+1,val[nq]=-Inf;
    35     fa[nq]=fa[q],fa[q]=fa[np]=nq;
    36     memcpy(ch[nq],ch[q],sizeof(ch[q]));
    37     for (;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    38   }
    39   return;
    40 }
    41 
    42 il void dfs(RG int x){
    43   Mx[x]=Mn[x]=val[x];
    44   for (RG int i=head[x],v;i;i=g[i].nt){
    45     v=g[i].to,dfs(v),sum[l[x]]+=1LL*sz[x]*sz[v],sz[x]+=sz[v];
    46     if (Mx[x]!=-Inf && Mx[v]!=-Inf) res[l[x]]=max(res[l[x]],1LL*Mx[x]*Mx[v]);
    47     if (Mn[x]!=-Inf && Mn[v]!=-Inf) res[l[x]]=max(res[l[x]],1LL*Mn[x]*Mn[v]);
    48     Mx[x]=max(Mx[x],Mx[v]),Mn[x]=min(Mn[x],Mn[v]); if (Mn[x]==-Inf) Mn[x]=Mn[v];
    49   }
    50   return;
    51 }
    52 
    53 int main(){
    54 #ifndef ONLINE_JUDGE
    55   freopen("savour.in","r",stdin);
    56   freopen("savour.out","w",stdout);
    57 #endif
    58   n=gi(),scanf("%s",s+1),len=strlen(s+1),val[la=++tot]=-Inf;
    59   for (RG int i=1;i<=n;++i) a[i]=gi(),res[i]=-inf; res[0]=-inf;
    60   for (RG int i=len;i;--i) add(s[i]-'a'),val[la]=a[i];
    61   for (RG int i=2;i<=tot;++i) insert(fa[i],i); dfs(1);
    62   for (RG int i=n-1;i>=0;--i) sum[i]+=sum[i+1],res[i]=max(res[i],res[i+1]);
    63   for (RG int i=0;i<n;++i) printf("%lld %lld
    ",sum[i],sum[i] ? res[i] : 0);
    64   return 0;
    65 }
  • 相关阅读:
    (4)UIView和父子控件
    (2)第一个IOS程序
    svn本地目录结构for window
    (1)xcode基本设置和控制器等介绍
    git版本控制 for window安装和命令行使用
    linux虚拟机如何配置网卡信息(确保两台服务器通信)
    linux系统中firewalld防火墙管理工具firewallcmd(CLI命令行)
    linux系统中firewalld防火墙管理工具firewallconfig(GUI图形用户界面)
    linux系统中使用nmtui命令配置网络参数(图形用户界面)
    网卡是什么?
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7630244.html
Copyright © 2011-2022 走看看