可能是最傻的做法了

暴力单调栈+\(st\)表

首先看到这道题就基本知道这是个\(SA\)了,先无脑敲上\(SA\)和求\(height\)的板子

之后尝试搞一下第一问

发现第一问就是求出满足\(lcp(i,j)>=k\)的\((i,j)\)有多少对

我们可以用一个暴力合并的单调栈来做

现在的问题转化为求出\(height\)数组所有子区间的最小值的和

我们可以考虑一个动态往序列末尾加数的过程

也就是我们往末尾加一个数都会和之前所有的数形成一个新的区间

考虑快速算出这些区间的最小值的和

我们可以对每一个数存储一个\(a_i\),表示\(i\)到当前序列末尾的最小值是多少

我们每次加入一个数可以对更新一下所有的\(a_i\),把所有比当前加入的数大的\(a_i\)变成当前数就好了

这不就\(T\)了吗

我们发现我们只需要求出所有\(a_i\)的和,并不需要关心这个\(i\)来自哪里,于是我们可以把相等的\(a_i\)放在一起计算,也就是每次新加入一个数就暴力扫一遍把那些比当前加入数大的合并到一个\(a_i\)

看起来复杂度并不科学,但是最坏情况下就相当于是一个线段树的复杂度了,\(O(n)\)的,跑的还挺快的

同时还需要维护一个时间戳,在被合并的时候利用时间戳统计一下这个元素的贡献

之后第二问,我们可以直接强上单调栈

左右两边都先用单调栈扫一遍,扫出每个点往左往右能最远达到哪里,之后我们用一个\(st\)表维护区间的最大值和最小值,每次只需要从这个点左边的区间和右边的区间里选出最大值和最小值来组合就行了

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define re register
#define LL long long
#define maxn 300005
inline LL read()
{
re char c=getchar();re LL x=0,r=1;
while(c<'0'||c>'9') {if(c=='-') r=-1;c=getchar();}
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return r*x;
}
int n,m,top;
int a[maxn],cnt[maxn],T[maxn],L[maxn],R[maxn];
char S[maxn];
int tp[maxn],tax[maxn],sa[maxn],rk[maxn],het[maxn],log_2[maxn],st[maxn];
LL pre[maxn],Ans[maxn];
LL St[2][maxn][20];
inline void qsort()
{
for(re int i=0;i<=m;i++) tax[i]=0;
for(re int i=1;i<=n;i++) tax[rk[i]]++;
for(re int i=1;i<=m;i++) tax[i]+=tax[i-1];
for(re int i=n;i;--i) sa[tax[rk[tp[i]]]--]=tp[i];
}
inline LL max(LL a,LL b){return (a>b)?a:b;}
inline LL min(LL a,LL b){return (a<b)?a:b;}
inline LL ask(int o,int l,int r)
{
int k=log_2[r-l+1];
if(o) return max(St[1][l][k],St[1][r-(1<<k)+1][k]);
else return min(St[0][l][k],St[0][r-(1<<k)+1][k]);
}
int main()
{
n=read();scanf("%s",S+1);
memset(St[0],0x3f3f3f3f,sizeof(St[0]));
memset(St[1],-0x3f3f3f3f,sizeof(St[1]));
memset(Ans,-0x3f3f3f3f,sizeof(Ans));
m=750;
for(re int i=1;i<=n;i++) rk[i]=S[i],tp[i]=i;
qsort();
for(re int w=1,p=0;p<n;m=p,w<<=1)
{
p=0;
for(re int i=1;i<=w;i++) tp[++p]=n-w+i;
for(re int i=1;i<=n;i++) if(sa[i]>w) tp[++p]=sa[i]-w;
qsort();
for(re int i=1;i<=n;i++) std::swap(rk[i],tp[i]);
rk[sa[1]]=p=1;
for(re int i=2;i<=n;i++) rk[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w])?p:++p;
}
int k=0;
for(re int i=1;i<=n;i++)
{
if(k) --k;
int j=sa[rk[i]-1];
while(S[i+k]==S[j+k]) ++k;
het[rk[i]]=k;
}
for(re int i=2;i<=n;i++)
{
int now=1;
while(top&&a[top]>=het[i])
now+=cnt[top],pre[a[top]]+=(LL)((LL)i-(LL)T[top])*(LL)cnt[top],top--;
a[++top]=het[i],T[top]=i,cnt[top]=now;
}
while(top) pre[a[top]]+=(LL)((LL)n+1ll-(LL)T[top])*(LL)cnt[top],top--;
for(re int i=n-1;i>=0;--i) pre[i]+=pre[i+1]; for(re int i=1;i<=n;i++)
{
while(top&&het[i]<het[st[top]]) R[st[top]]=i,top--;
st[++top]=i;
}
while(top) R[st[top]]=n+1,top--;
for(re int i=n;i;--i)
{
while(top&&het[i]<het[st[top]]) L[st[top]]=i,top--;
st[++top]=i;
}
while(top) L[st[top]]=1,top--; for(re int i=1;i<=n;i++) St[0][rk[i]][0]=St[1][rk[i]][0]=read();
for(re int i=2;i<=n;i++) log_2[i]=1+log_2[i>>1];
for(re int j=1;j<=19;j++)
for(re int i=1;i+(1<<j)-1<=n;i++)
St[0][i][j]=min(St[0][i][j-1],St[0][i+(1<<(j-1))][j-1]),
St[1][i][j]=max(St[1][i][j-1],St[1][i+(1<<(j-1))][j-1]); for(re int i=1;i<=n;i++)
{
int l=L[i],r=R[i]-1;
if(l>i-1) continue;
if(i>r) continue;
LL A=ask(1,l,i-1),B=ask(0,l,i-1),C=ask(1,i,r),D=ask(0,i,r);
if(Ans[het[i]]<A*C) Ans[het[i]]=A*C; if(Ans[het[i]]<B*D) Ans[het[i]]=B*D;
if(Ans[het[i]]<A*D) Ans[het[i]]=A*D; if(Ans[het[i]]<B*C) Ans[het[i]]=B*C;
}
for(re int i=n-1;i>=0;--i) Ans[i]=max(Ans[i],Ans[i+1]);
for(re int i=0;i<n;i++)
if(pre[i]) printf("%lld %lld\n",pre[i],Ans[i]);
else printf("%lld ",pre[i]),putchar(48),putchar(10);
return 0;
}

【[NOI2015]品酒大会】的更多相关文章

  1. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  2. [UOJ#131][BZOJ4199][NOI2015]品酒大会 后缀数组 + 并查集

    [UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...

  3. 洛谷 P2178 [NOI2015]品酒大会 解题报告

    P2178 [NOI2015]品酒大会 题目描述 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发"首席品酒家"和 ...

  4. 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集

    [BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...

  5. [UOJ#131][BZOJ4199][NOI2015]品酒大会

    [UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...

  6. BZOJ_4199_[Noi2015]品酒大会_后缀自动机

    BZOJ_4199_[Noi2015]品酒大会_后缀自动机 Description 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 酒家”和“首席 ...

  7. [NOI2015]品酒大会(SA数组)

    [NOI2015]品酒大会 题目描述 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发"首席品酒家"和" ...

  8. 洛谷P2178 [NOI2015]品酒大会 后缀数组+单调栈

    P2178 [NOI2015]品酒大会 题目链接 https://www.luogu.org/problemnew/show/P2178 题目描述 一年一度的"幻影阁夏日品酒大会" ...

  9. [NOI2015] 品酒大会 - 后缀数组,并查集,STL,启发式合并

    [NOI2015] 品酒大会 Description 对于每一个 \(i \in [0,n)\) 求有多少对后缀满足 LCP 长度 \(\le i\) ,并求满足条件的两个后缀权值乘积的最大值. So ...

  10. [BZOJ4199][NOI2015]品酒大会

    #131. [NOI2015]品酒大会 统计 描述 提交 自定义测试 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项, ...

随机推荐

  1. [android] 手机卫士接收打电话广播显示号码归属地

    使用广播接收者接收打电话的意图,显示号码归属地 新建一个类OutCallReceiver继承系统的BroadcastReceiver 重写onReceive()方法 调用getResultData() ...

  2. Java中使用json时java.lang.NoClassDefFoundError: net/sf/ezmorph/Morpher问题解决

    下面代码: public static void main(String[] args) { JSONObject obj = new JSONObject(); obj.put("msg& ...

  3. Myeclipse安装与破解

    安装包+破解包 链接:https://pan.baidu.com/s/1G4mYsTOMDixyr2UmdqqY5A 提取码:a2n8 红色框框内的是安装包,蓝色框框内的是破解包 安装过程中比较简单, ...

  4. EF_CRUD

  5. 浏览器根对象navigator之客户端检测

    Navigator的5个主要属性: appName:Web浏览器的名称 appVersion:浏览器的版本号和其他版本信息 userAgent:浏览器在它的USER-AGENT HTTP标题中发送的字 ...

  6. 基于OpenMP的C++并行编程简单示例

    示例要求:在整数A和B之间找到符合条件的值X,使f(X)=C. 示例代码(需要在VS中开启OpenMP支持): #include<iostream> #include<time.h& ...

  7. Unexpected token o in JSON at position 1 at JSON.parse (<anonymous>) SyntaxError: Unexpected token R in JSON at position 0 at JSON.parse (<anonymous>)

    这个问题在之前做项目时碰到过一次,当时按照网上的做法,去掉JSON.parse()这一层转换后就没有这个报错了,数据也能正常使用,就没多想,也没深究是什么原因.可是这次又碰到了,所以这次我必须要弄明白 ...

  8. 关于Datastage资料库的一点小发现

    这里的资料库,指的是Datastage Metadata层,在Datastage7.5以后,需要在安装Datastage时安装一个数据库用于存放用户数据. 昨天领导要求安装Datastage集群/高可 ...

  9. LeakCanary上传 leak trace 到服务器

    你可以改变处理完成的默认行为,将 leak trace 和 heap dump 上传到你的服务器以便统计分析. 创建一个 LeakUploadService, 最简单的就是继承 DisplayLeak ...

  10. Android自定义View探索—生命周期

    Activity代码: public class FiveActivity extends AppCompatActivity { private MyView myView; @Override p ...