码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4199 [Noi2015]品酒大会

时间:2017-10-06 13:53:34      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:min   blank   scan   tar   最小值   log   str   ble   getchar   

题面:见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\n",sum[i],sum[i] ? res[i] : 0);
64   return 0;
65 }

 

bzoj4199 [Noi2015]品酒大会

标签:min   blank   scan   tar   最小值   log   str   ble   getchar   

原文地址:http://www.cnblogs.com/wfj2048/p/7630244.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!