Portal -->loj6198

Solution

​  (为什么感觉loj上面这几道后缀数组的题。。套路都是一样的啊qwq)

​  同样也是。。考虑某个区间\(height[i]\)的最小值的贡献

​​  记\(solve(i,j)\)表示统计\(rk\)值\(\in [l,r]\)的后缀对答案的贡献,那么我们有一个十分简单粗暴的想法,我们用ST表求出\([l,r]\)区间内的\(height\)最小值\(x\),记它的位置为\(mid\),如果说一开始我们先按照\(rk\)的顺序建一棵可持久化trie,那么这个时候我们就可以直接枚举\(rk\)值\(\in [l,mid-1]\)区间的后缀的\(w\),然后在\([mid,r]\)的区间内的trie上查\(w\)的最大异或值就好了

​​  但是现在的问题是,这样显然会超时

​  这里我们其实可以用一个。。类似启发式合并的思想,我们每次比较\([l,mid-1]\)和\([mid,r]\)这两个区间谁比较短,然后我们就枚举较短的区间内的\(w\)值,在另一个区间的trie上查然后更新

​  这样的复杂度我不太会证qwq但是能够过掉qwq

​​  然后可能因为我的递归写的太挫了要手动扩栈才能愉快AC菜醒qwq

​  

​  代码大概长这个样子

#pragma comment(linker,"/STACK:102400000,102400000")
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define mp make_pair
#define Pr pair<int,int>
#define ll long long
using namespace std;
const int N=1e5+10,TOP=16;
char s[N];
int w[N];
int n;
ll ans,Cnt;
namespace Trie{/*{{{*/
int ch[N*2*30][2],cnt[N*2*30],rt[N];
int tot;
int newnode(int x){
ch[++tot][0]=ch[x][0]; ch[tot][1]=ch[x][1];cnt[tot]=cnt[x];
return tot;
}
void _insert(int x,int &now,int delta,int d){
now=newnode(x);
++cnt[now];
if (d<0) return;
int which=delta>>d&1;
_insert(ch[x][which],ch[now][which],delta,d-1);
}
void insert(int x,int delta){_insert(!x?0:rt[x-1],rt[x],delta,TOP);}
int _get_mx(int l,int r,int delta,int d){
if (d<0) return 0;
int which=delta>>d&1;
if (cnt[ch[r][which^1]]-cnt[ch[l][which^1]])
return _get_mx(ch[l][which^1],ch[r][which^1],delta,d-1)+(1<<d);
return _get_mx(ch[l][which],ch[r][which],delta,d-1);
}
int get_mx(int l,int r,int delta){
if (l==-1||r==-1) return 0;
return _get_mx(rt[l-1],rt[r],delta,TOP);
}
}/*}}}*/
namespace Sa{/*{{{*/
int a[N],b[N],c[N],sa[N],height[N],rk[N];
int mn[N][TOP+1],loc[N][TOP+1];
int mx;
bool cmp(int x,int y,int len,int *r)
{return r[x]==r[y]&&r[x+len]==r[y+len];}
void sort(int n){
for (int i=0;i<=mx;++i) c[i]=0;
for (int i=1;i<=n;++i) ++c[a[b[i]]];
for (int i=1;i<=mx;++i) c[i]+=c[i-1];
for (int i=n;i>=1;--i) sa[c[a[b[i]]]--]=b[i];
}
void get_sa(int n){
int cnt=0; mx=0;
for (int i=1;i<=n;++i) a[i]=s[i]-'a'+1,b[i]=i,mx=max(mx,a[i]);
sort(n);
for (int len=1;cnt<n;len<<=1){
cnt=0;
for (int i=n-len+1;i<=n;++i) b[++cnt]=i;
for (int i=1;i<=n;++i)
if (sa[i]>len)
b[++cnt]=sa[i]-len;
sort(n);
swap(a,b);
cnt=1; a[sa[1]]=1;
for (int i=2;i<=n;a[sa[i++]]=cnt)
if (!cmp(sa[i-1],sa[i],len,b)) ++cnt;
mx=cnt;
}
}
void rmq(){
for (int i=1;i<=n;++i) mn[i][0]=height[i],loc[i][0]=i;
for (int j=1;j<=TOP;++j)
for (int i=n-(1<<j)+1;i>=1;--i)
if (mn[i][j-1]<mn[i+(1<<j-1)][j-1])
mn[i][j]=mn[i][j-1],loc[i][j]=loc[i][j-1];
else
mn[i][j]=mn[i+(1<<j-1)][j-1],loc[i][j]=loc[i+(1<<j-1)][j-1];
}
Pr get_lcp(int x,int y){//ranks
if (x==y) return mp(n-sa[x]+1,x);
if (x>y) swap(x,y);
++x;
int len=y-x+1,lg=(int)(log(1.0*len)/log(2.0));
if (mn[x][lg]<mn[y-(1<<lg)+1][lg])
return mp(mn[x][lg],loc[x][lg]);
else
return mp(mn[y-(1<<lg)+1][lg],loc[y-(1<<lg)+1][lg]);
}
void get_height(int n){
for (int i=1;i<=n;++i) rk[sa[i]]=i;
int k=0;
for (int i=1;i<=n;++i){
if (k) --k;
while (s[i+k]==s[sa[rk[i]-1]+k]) ++k;
height[rk[i]]=k;
}
rmq();
}
void solve(int l,int r){
if (l>=r) return;
Pr tmp=get_lcp(l,r);
int mid=tmp.second,lcp=tmp.first;
if (r-mid+1<mid-1-l+1){
for (int i=mid;i<=r;++i)
ans=max(ans,1LL*lcp+Trie::get_mx(l,mid-1,w[sa[i]]));
}
else{
for (int i=l;i<=mid-1;++i)
ans=max(ans,1LL*lcp+Trie::get_mx(mid,r,w[sa[i]]));
}
solve(l,mid-1);
solve(mid,r);
}
}/*}}}*/ int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%d",&n);
scanf("%s",s+1);
for (int i=1;i<=n;++i) scanf("%d",w+i);
Sa::get_sa(n);
Sa::get_height(n);
//for (int i=1;i<=n;++i) printf("%d ",Sa::sa[i]); printf("\n");
for (int i=1;i<=n;++i)
Trie::insert(i,w[Sa::sa[i]]);
ans=0;
Sa::solve(1,n);
printf("%lld\n",ans);
}

【loj6198】谢特的更多相关文章

  1. [LOJ6198]谢特

    loj description 给你一个字符串和一个数组\(w_i\),定义\(\mbox{LCP}(i,j)\)为\(i,j\)两个后缀的最长公共前缀.求\(\max_{i,j}\mbox{LCP} ...

  2. loj6198谢特 后缀数组+并查集+Trie

    先把问题放在后缀数组上考虑 已知两个数组a b,求min(a[i],...,a[j])+(b[i]^b[j])的最大值 套路题 初始每个点都是一个小连通块 把a按从大到小的顺序加入,计算当前加入边作为 ...

  3. 谢欣伦 - OpenDev原创教程 - 媒体开发库libMedia

    libMedia是一个免费的简单的媒体开发库,其中的接口类与函数大都以小写的x打头,来源于我的姓氏首字母(谢欣伦). 下载 OpenDev for VS2012 libMedia提供四大功能,一是视频 ...

  4. 谢欣伦 - OpenDev原创教程 - 蓝牙设备查找类CxBthRadio & CxBthRadioFind

    这是一个精练的蓝牙设备查找类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxBthRadioFind的使用如下: void CU ...

  5. 谢欣伦 - OpenDev原创教程 - 服务端套接字类CxServerSocket

    这是一个精练的服务端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxServerSocket的使用如下(以某个叫做CSo ...

  6. 谢欣伦 - OpenDev原创教程 - 蓝牙设备查找类CxBthRemoteDeviceFind

    这是一个精练的蓝牙设备查找类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxBthRemoteDeviceFind的使用如下: ...

  7. 谢欣伦 - OpenDev原创教程 - 无连接套接字类CxUdpSocket

    这是一个精练的无连接套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxUdpSocket的使用如下(以某个叫做CSomeC ...

  8. 谢欣伦 - OpenDev原创教程 - 串口类CxSerial

    这是一个精练的串口类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. 串口类CxSerial的使用如下(以某个叫做CSomeClass ...

  9. 谢欣伦 - OpenDev原创教程 - 客户端套接字类CxClientSocket

    这是一个精练的客户端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxClientSocket的使用如下(以某个叫做CSo ...

随机推荐

  1. JMeter:全面的乱码解决方案【转】

    本文是转自https://www.cnblogs.com/mawenqiangios/p/7918583.html 感谢分享者   中文乱码一直都是比较让人棘手的问题,我们在使用Jmeter的过程中, ...

  2. 面向 Unity* 软件和虚拟现实的优化:运行时生成内容

    优化游戏以实现高性能一直是游戏开发过程中的一个重要因素.虽然开发人员一直尝试将硬件推向极致,但当移动游戏成为主流时,优化技术变得尤为突出.Unity* 软件.Unreal* 等常见引擎最初都是面向 P ...

  3. 【坚持】Selenium+Python学习之从读懂代码开始 DAY1

    学习Selenium+Python已经好几个月了,但越学发现不懂的东西越多. 感觉最大的问题还是在于基础不扎实,决定从头开始,每天坚持读代码,写代码. 相信量变一定能到质变!!! 2018/05/09 ...

  4. JAVA学习笔记--字符串概述

    一.String类 String类代表字符串,是由字符构成的一个序列.创建String对象的方法很简单,有以下几种: 1)用new来创建: String s1 = new String("m ...

  5. spring JDBC 事务管理

    spring JDBC 事务管理 一.Spring 中的JDBC Spring中封装了JDBC的ORM框架,可以用它来操作数据,不需要再使用外部的OEM框架(MyBatis),一些小的项目用它. 步骤 ...

  6. int 和 Integer的区别

    int是基本类型,默认值为0,int a=5;a只能用来计算,一般作为数值参数. Integer是引用类型,默认值为null, Integer b=5;b是一个对象,它可以有很多方法,一般做数值转换, ...

  7. Team Work Ⅲ

    Regal-Lighting团队设计 分工思考 本次大作业我的分工定位是:Unit及子类,主要设计实现建筑类的功能. 在上一篇博客我介绍了我的继承方案和接口设定,这一篇粗略的介绍一下实现部分 Defe ...

  8. 【leetcode】54.Spiral Matrix

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  9. mysql中变量

    mysql中的变量: mysql中,有两种变量形式: 普通变量: 不带“@”符号: 定义形式: declare  变量名  类型名   [default  默认值]: //普通变量必须先这样定义 赋值 ...

  10. hdu mophues

    在比赛的时候,被这个题目虐死了,这一周中每当我有空闲时间我就总是思索这个题目的解题方法. 终于在自己学过了mobius反演,并且看过别人写得解题思路后自己有了思路. 下面说说我的解题思路吧. 首先题目 ...