洛谷P2178 [NOI2015]品酒大会 后缀数组+单调栈
P2178 [NOI2015]品酒大会
题目链接
https://www.luogu.org/problemnew/show/P2178
题目描述
一年一度的“幻影阁夏日品酒大会”隆重开幕了。大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加。
在大会的晚餐上,调酒师 Rainbow 调制了 n 杯鸡尾酒。这 n 杯鸡尾酒排成一行,其中第 n 杯酒 (\(1 ≤ i ≤ n\)) 被贴上了一个标签 \(s_i\) ,每个标签都是 26个小写 英文字母之一。设$ str(l, r)$表示第 l 杯酒到第 r 杯酒的 r - l + 1个标签顺次连接构成的字符串。若 \(str(p,p_0)=str(q,q_0)\),其中 \(1 ≤ p ≤ p_0 ≤ n,1 ≤ q ≤ q_0≤ n, p ≠ q,p_0-p+1 = q_0 - q + 1 = r\),则称第 p 杯酒与第 q 杯酒是“ r 相似” 的。当然两杯“ r 相似”(\(r > 1\))的酒同时也是“ 1 相似”、“ 2相似”、……、“ (r - 1) 相似”的。特别地,对于任意的 \(1 ≤ p ,q ≤ n,p ≠ q\),第 p杯酒和第 q 杯酒都 是“ 0 相似”的。
在品尝环节上,品酒师 Freda 轻松地评定了每一杯酒的美味度,凭借其专业的水准和经验成功夺取了“首席品酒家”的称号,其中第 i杯酒 (1 ≤ i ≤ n) 的 美味度为 a_i。现在 Rainbow 公布了挑战环节的问题:本次大会调制的鸡尾酒有一个特点,如果把第 p 杯酒与第 q 杯酒调兑在一起,将得到一杯美味度为 $a_p\times a_q $的 酒。现在请各位品酒师分别对于 r = 0,1,2,⋯,n-1 ,统计出有多少种方法可以 选出 2 杯“ r 相似”的酒,并回答选择 2 杯“r 相似”的酒调兑可以得到的美味度的最大值。
输入输出格式
输入格式:
第 1 行包含 111 个正整数 n ,表示鸡尾酒的杯数。
第 2 行包含一个长度为 n的字符串 S,其中第 i 个字符表示第 i 杯酒的标签。
第 3 行包含 n 个整数,相邻整数之间用单个空格隔开,其中第 i 个整数表示第 i 杯酒的美味度 a_i 。
输出格式:
包括 nnn 行。
第 i 行输出 2 个整数,中间用单个空格隔开。第 111 个整 数表示选出两杯“ (i - 1)相似”的酒的方案数,第 2 个整数表示选出两杯 “ (i−1) 相似”的酒调兑可以得到的最大美味度。若不存在两杯“ (i - 1) 相似” 的酒,这两个数均为 0 。
输入输出样例
输入样例#1:
10
ponoiiipoi
2 1 4 7 4 8 3 6 4 7
输出样例#1:
45 56
10 56
3 32
0 0
0 0
0 0
0 0
0 0
0 0
0 0
输入样例#2:
12
abaabaabaaba
1 -2 3 -4 5 -6 7 -8 9 -10 11 -12
输出样例#2:
66 120
34 120
15 55
12 40
9 27
7 16
5 7
3 -4
2 -4
1 -4
0 0
0 0
说明
【时限1s,内存512M】
题意
给你一个字符串,任意两个后缀的相似度为0到LCP,求相似度为0~n-1的方案数。对于相似度k,如果第i位和第j位的LCP>=k,那么k相似度方案加一。 并且每个位置i,还有一个权值a[i],对于每个k相似度求最大的a[i] * a[j](i和j如上所述)
题解
其实已经做过一遍了,但是依然调了好久,真是悲伤。
其实思想并不是很难,我们先打个后缀数组板子,然后考虑height数组。我们以前怎么找后缀i和后缀j的lcp,不就是求他们在height数组之间的最小值吗。那么考虑对于height数组每个位置i的贡献,自然就是找左边第一个小于它的位置记作L[i],同样找到右边R[i],那么只要两个后缀x,y满足\(L[i]\leq x<i\leq y<R[i]\),那么x,y的lcp就是height[i],这样sum[height[i]]+=(R[i]-i)*(i-L[i]), max的求法也是类似的。
这个用单调站栈很好做,但是细节确实需要注意一下。
好久没打后缀数组了,memset(c,0,sizeof(int)*(m+1)) 少写了+1,
一开始INF定义为123456789,后来才知道原来\(10^9>123456789\),调了半天,真是菜的真实。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x7f7f7f7f
#define N 600050
ll lmx[N],rmx[N],lmi[N],rmi[N],L[N],R[N],sum[N],mx[N],w[N];
int sk[N];
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
struct SuffixArray
{
char s[N];
int c[N],t1[N<<1],t2[N<<1],kth[N],rk[N],he[N],n;
int *x=t1,*y=t2;
void BuildKth()
{
int m=300;
memset(c,0,sizeof(int)*(m+1));
for(int i=1;i<=n;i++)c[x[i]=s[i]]++;
for(int i=1;i<=m;i++)c[i]+=c[i-1];
for(int i=n;i>=1;i--)kth[c[x[i]]--]=i;
for(int k=1;k<=n;k<<=1)
{
memset(c,0,sizeof(int)*(m+1));
int p=0;
for(int i=n-k+1;i<=n;i++)y[++p]=i;
for(int i=1;i<=n;i++)if (kth[i]-k>0)y[++p]=kth[i]-k;
for(int i=1;i<=n;i++)c[x[y[i]]]++;
for(int i=1;i<=m;i++)c[i]+=c[i-1];
for(int i=n;i>=1;i--)kth[c[x[y[i]]]--]=y[i];
swap(x,y);
x[kth[1]]=p=1;
for(int i=2;i<=n;i++)
x[kth[i]]=y[kth[i]]==y[kth[i-1]]&&y[kth[i]+k]==y[kth[i-1]+k]?p:++p;
m=p;
if (m==n)break;
}
}
void GetHeight()
{
for(int i=1;i<=n;i++)rk[kth[i]]=i;
int k=0;
for(int i=1;i<=n;i++)
{
int j=kth[rk[i]-1];
if (k)k--;
while(s[i+k]==s[j+k])k++;
he[rk[i]]=k;
}
}
void solve()
{
int top=0;
he[n+1]=-1;
he[1]=-1;
for(int i=1;i<=n+1;i++)
{
mx[i]=-1LL*INF*INF;
ll tpmx=w[sk[top]],tpmi=w[sk[top]];
while(top&&he[i]<=he[sk[top]])
{
R[sk[top]]=i;
rmx[sk[top]]=tpmx;
rmi[sk[top]]=tpmi;
tpmx=max(tpmx,lmx[sk[top]]);
tpmi=min(tpmi,lmi[sk[top]]);
top--;
}
L[i]=sk[top];
lmx[i]=tpmx;
lmi[i]=tpmi;
sk[++top]=i;
}
int num=0;
for(int i=2;i<=n;i++)
{
num=max(num,he[i]);
mx[he[i]]=max(mx[he[i]],lmx[i]*rmx[i]);
mx[he[i]]=max(mx[he[i]],lmi[i]*rmi[i]);
sum[he[i]]+=1LL*(i-L[i])*(R[i]-i);
}
for(int i=num+1;i<=n;i++)mx[i]=0;
for(int i=num-1;i>=0;i--)mx[i]=max(mx[i],mx[i+1]),sum[i]+=sum[i+1];
for(int i=0;i<=n-1;i++)printf("%lld %lld\n",sum[i],mx[i]);
}
}A;
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
read(A.n);
for(int i=1;i<=A.n;i++)read_char(A.s[i]);
A.BuildKth();
A.GetHeight();
for(int i=1;i<=A.n;i++)read(w[A.rk[i]]);
A.solve();
}
洛谷P2178 [NOI2015]品酒大会 后缀数组+单调栈的更多相关文章
- BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)
BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...
- 洛谷P2178 [NOI2015]品酒大会(后缀自动机 线段树)
题意 题目链接 Sol 说一个后缀自动机+线段树的无脑做法 首先建出SAM,然后对parent树进行dp,维护最大次大值,最小次小值 显然一个串能更新答案的区间是\([len_{fa_{x}} + 1 ...
- 洛谷 P2178 [NOI2015]品酒大会 解题报告
P2178 [NOI2015]品酒大会 题目描述 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发"首席品酒家"和 ...
- 洛谷P2178 [NOI2015]品酒大会
题目描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainb ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- [UOJ#131][BZOJ4199][NOI2015]品酒大会 后缀数组 + 并查集
[UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...
- 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集
[BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...
- [NOI2015] 品酒大会 - 后缀数组,并查集,STL,启发式合并
[NOI2015] 品酒大会 Description 对于每一个 \(i \in [0,n)\) 求有多少对后缀满足 LCP 长度 \(\le i\) ,并求满足条件的两个后缀权值乘积的最大值. So ...
- BZOJ 4199: [Noi2015]品酒大会( 后缀数组 + 并查集 )
求出后缀数组后, 对height排序, 从大到小来处理(r相似必定是0~r-1相似), 并查集维护. 复杂度O(NlogN + Nalpha(N)) ------------------------- ...
随机推荐
- bus error(总线错误)
转自 http://blog.csdn.net/todd911/article/details/8813321 在<C专家编程>中提到了总线错误bus error(core dumped) ...
- scrapy框架之进阶
五大核心组件 - 引擎(Scrapy) 用来处理整个系统的数据流处理, 触发事务(框架核心) - 调度器(Scheduler) 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. ...
- 学python必须知道的30个技巧
收集这些有用的捷径技巧 1. 原地进行交换两个数字 我们对赋值的右侧进行一个新的元组,左侧解析(unpack)那个(未被引用的)元组到变量 <a> 和 <b> 赋值完成时,新的 ...
- jinja2-宏,include, import
一 宏 宏类似常规编程语言中的函数.它们用于把常用行为作为可重用的函数,取代 手动重复的工作.如果宏在不同的模板中定义,你需要首先使用 import,比如 {% macro input(name, v ...
- Java并发指南7:JUC的核心类AQS详解
一行一行源码分析清楚AbstractQueuedSynchronizer 转自https://www.javadoop.com/post/AbstractQueuedSynchronizer#toc4 ...
- Protocol Buffers学习笔记
Protocol Buffers学习笔记 1. 简介 Protocol Buffers是google发明的一种数据交换格式,独立于语言,独立于平台.与其他的数据交换格式有所不同,Protocol Bu ...
- java安全学习-环境准备/基础知识
补java的坑,开始! 1.Intellij一些快捷键 intell常用快捷键: ctrl+n 快速查找定位类的位置 ctrl+q 快速查看某个类的文档信息 shift + F6 快速类.变量重命名 ...
- [Bayes] *Bayesian Classifier for Face Recognition
Bayesian在识别领域的贡献,着实吸引人 阅读笔记 Gabor特征 (简介,另单独详述) 通过上面的分析,我们知道了,一个Gabor核能获取到图像某个频率邻域的响应情况,这个响应结果可以看做是图像 ...
- 关于Jmeter测试移动端应用时提示非法登录,不是合法的登录设备时的解决办法
当Jmeter测试移动端应用时提示非法登录,不是合法的登录设备时的解决办法:只需要在jmeter的http信息头管理器中配置相应的设备信息,可通过抓包工具得到:即头信息Header中的Miscella ...
- iOS-iOS 支付 [支付宝、银联、微信](转)
支付宝iOSsdk官方下载sdk地址:https://b.alipay.com/order/productDetail.htm?productId=2013080604609654&tabId ...