Luogu2178 NOI2015 品酒大会 SA、并查集
感觉题目讲的很不清楚……
题目意思就是给出一个长度为\(n\)的字符串,求对于\(r=0,1,...,n-1\),求出\(LCP(suffix_p,suffix_q) \geq r\)的无序数对\((p,q)\)的数目,并令一对无序数对的价值为\(val_p \times val_q\),则还要求对于每一个\(r\),所有满足上述条件的无序数对中的最大价值
跟后缀\(LCP\)长度有关,直接上\(SA\)。求出\(sa\)数组和\(height\)数组,我们考虑如何实现对于每一个\(r\)的询问快速求出答案。不妨将\(r\)从大到小求解,那么对于某一个后缀\(sa_k\),满足\(LCP(suffix_{sa_p} , suffix_{sa_k}) \geq r\)的\(p\)一定是一段区间,而且这一段区间随着\(r\)的缩小不断增大。
然后我们考虑如何拓展区间。考虑对于\(height_k=q\),当\(r>q\)的时候\(k\)位置两端的区间不会越过\(k-1\)与\(k\),而当\(r \leq q\)时这两段区间就会合成一段区间。这个显然是可以使用并查集维护的,并且可以比较轻松地在并查集上维护最大价值。
#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
#define lch Tree[x].l
#define rch Tree[x].r
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
}
const int MAXN = 3e5 + 10;
int fa[MAXN] , val[MAXN] , valMax[MAXN][2] , valMin[MAXN][2];
int sa[MAXN] , rk[MAXN] , pot[MAXN] , tp[MAXN << 1] , h[MAXN];
int ind[MAXN] , size[MAXN] , N , maxN = 26;
char s[MAXN];
long long Max , cnt , ans[MAXN][2];
int find(int x){
return fa[x] == x ? x : (fa[x] = find(fa[x]));
}
void Debug(){
for(int i = 1 ; i <= N ; ++i)
cout << sa[i] << ' ';
cout << endl;
for(int i = 1 ; i <= N ; ++i)
cout << ind[i] << ' ';
cout << endl << endl;
}
void input(){
N = read();
scanf("%s" , s + 1);
for(int i = 1 ; i <= N ; ++i){
val[i] = read();
if(val[i] < 0)
valMin[i][0] = val[i];
}
}
void sort(int p){
memset(pot , 0 , sizeof(pot));
for(int i = 1 ; i <= N ; ++i)
++pot[rk[i]];
for(int i = 1 ; i <= maxN ; ++i)
pot[i] += pot[i - 1];
for(int i = 1 ; i <= N ; ++i)
sa[++pot[rk[tp[i]] - 1]] = tp[i];
memcpy(tp , rk , sizeof(int) * (N + 1));
for(int i = 1 ; i <= N ; ++i)
rk[sa[i]] = rk[sa[i - 1]] + (tp[sa[i]] != tp[sa[i - 1]] || tp[sa[i] + p] != tp[sa[i - 1] + p]);
maxN = rk[sa[N]];
}
bool cmp(int a , int b){
return h[a] < h[b];
}
void init(){
memset(valMax , -0x3f , sizeof(valMax));
Max = -1ll * 0x3f3f3f3f * 0x3f3f3f3f;
for(int i = 1 ; i <= N ; ++i)
rk[tp[i] = i] = s[i] - 'a' + 1;
sort(0);
for(int i = 1 ; i <= N && maxN < N ; i <<= 1){
int cnt = 0;
for(int j = 1 ; j <= i ; ++j)
tp[++cnt] = N - i + j;
for(int j = 1 ; j <= N ; ++j)
if(sa[j] > i)
tp[++cnt] = sa[j] - i;
sort(i);
}
for(int i = 1 ; i <= N ; ++i){
if(rk[i] == 1)
continue;
int t = rk[i];
h[t] = max(0 , h[rk[i - 1]] - 1);
while(s[sa[t] + h[t]] == s[sa[t - 1] + h[t]])
++h[t];
ind[t] = t;
}
sort(ind + 2 , ind + N + 1 , cmp);
for(int i = 1 ; i <= N ; ++i){
fa[i] = i;
size[i] = 1;
valMax[i][0] = val[i];
}
}
inline void merge(int x , int y){
fa[x] = y;
int num[4] = {valMax[x][0] , valMax[x][1] , valMax[y][0] , valMax[y][1]};
sort(num , num + 4);
valMax[y][0] = num[3];
valMax[y][1] = num[2];
Max = max(Max , 1ll * valMax[y][0] * valMax[y][1]);
num[0] = valMin[x][0];
num[1] = valMin[x][1];
num[2] = valMin[y][0];
num[3] = valMin[y][1];
sort(num , num + 4);
valMin[y][0] = num[0];
valMin[y][1] = num[1];
if(1ll * valMin[y][0] * valMin[y][1])
Max = max(Max , 1ll * valMin[y][0] * valMin[y][1]);
cnt -= 1ll * size[x] * (size[x] - 1) / 2 + 1ll * size[y] * (size[y] - 1) / 2;
size[y] += size[x];
cnt += 1ll * size[y] * (size[y] - 1) / 2;
}
void work(){
int p = N;
for(int i = N - 1 ; i >= 0 ; --i){
while(p > 1 && h[ind[p]] == i){
merge(find(sa[ind[p]]) , find(sa[ind[p] - 1]));
--p;
}
if(cnt){
ans[i][0] = cnt;
ans[i][1] = Max;
}
}
}
void output(){
for(int i = 0 ; i <= N - 1 ; ++i)
cout << ans[i][0] << ' ' << ans[i][1] << '\n';
}
int main(){
input();
init();
work();
output();
return 0;
}
Luogu2178 NOI2015 品酒大会 SA、并查集的更多相关文章
- bzoj4199: [Noi2015]品酒大会 (并查集 && 后缀数组)
据说用后缀自动机 + dp也能做 然而并不会 后缀数组的做法呢 就是先建个后缀数组,求出height值,此时如果直接找,复杂度是n ^ 2的,肯定会超时. 但是height大的值是不会对小的产生影响的 ...
- [NOI2015]品酒大会(SA数组)
[NOI2015]品酒大会 题目描述 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发"首席品酒家"和" ...
- luogu2178/bzoj4199 品酒大会 (SA+单调栈)
他要求的就是lcp(x,y)>=i的(x,y)的个数和a[x]*a[y]的最大值 做一下后缀和,就只要求lcp=i的了 既然lcp(x,y)=min(h[rank[x]+1],..,[h[ran ...
- 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 ...
- [UOJ#131][BZOJ4199][NOI2015]品酒大会
[UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...
- 洛谷 P2178 [NOI2015]品酒大会 解题报告
P2178 [NOI2015]品酒大会 题目描述 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发"首席品酒家"和 ...
随机推荐
- Flutter 布局(八)- Stack、IndexedStack、GridView详解
本文主要介绍Flutter布局中的Stack.IndexedStack.GridView控件,详细介绍了其布局行为以及使用场景,并对源码进行了分析. 1. Stack A widget that po ...
- Android 裁剪人脸
人脸裁剪类 public final class FaceCj { private static BitmapFactory.Options BitmapFactoryOptionsbfo; priv ...
- mybatis学习系列二
1 参数处理(封装map过程)(23) 1.1)F5进入断点:Employee employee1=mapper.selectEmployeeByMap(map); 1.2)进入MapperProxy ...
- .net core HttpContext(Http上下文)
在.NET Core中,只有Controller才能直接使用 HttpContext ,其他地方需要通过HttpContextAccessor来访问
- 字符串通过在配置文件配置三个key来进行加密解密
在这里和大家分享一个加密util,相对于md5加密相信大家都已经很熟悉了吧,md5是不可逆的一种加密方式,虽说不可逆但是网上已经有了破解的方法,我这边分享一个免费的破解 网址给大家:https://w ...
- Web的攻击技术笔记
HTTP不具备必要的安全功能,就是一个通用的单纯协议机制,比如远程登录时会用到的SSH协议来说,SSH具备协议级别的认证及回话管理等功能,HTTP协议则没有.另外在架设SSH服务方面,任何人都可以轻易 ...
- MySQL sql_mode=only_full_group_by错误
今天在测试服务器上突然出现了这么一个MySQL的问题,同样的代码正式服没有问题,那肯定就是出在了配置上,查了一下原因才明白原来是数据库版本为5.7以上的版本, 默认是开启了 only_full_gro ...
- VRS待解决的问题——原因及解决方案
1.持续滤波失败(查看文档) 通过查看文档及代码 2.GAL卫星数为0的网元及原因 3.判断发的是否是单个基站(网元未固定),多个用户进行测试 4.网元固定率(采用文件输出) 5.是否频繁重复初始化 ...
- SQL Server2008 18456错误
1.以windows验证模式进入数据库管理器. 第二步:右击sa,选择属性: 在常规选项卡中,重新填写密码和确认密码(改成个好记的).把强制实施密码策略去掉. 第三步:点击状态选项卡:勾选 ...
- MySQL InnoDB Update和Crash Recovery流程
MySQL InnoDB Update和Crash Recovery流程 概要信息 首先介绍了Redo,Undo,Log Sequence Number (LSN),Checkpoint,Rollba ...