【LCP】圈圈-字符串哈希/后缀数组

题意:       shy有一个队列a[1], a[2],…,a[n]。现在我们不停地把头上的元素放到尾巴上。在这过程中我们会得到n个不同的队列,每个队列都是a[k],a[k+1],…,a[n],a[1],…,a[k-1]的形式。在这些队列中,我们可以找到字典序最小的。        shy无聊的
摘要由CSDN通过智能技术生成
题意:

       shy有一个队列a[1], a[2],…,a[n]。现在我们不停地把头上的元素放到尾巴上。在这过程中我们会得到n个不同的队列,每个队列都是a[k],a[k+1],…,a[n],a[1],…,a[k-1]的形式。在这些队列中,我们可以找到字典序最小的。
       shy无聊的时候会给队列的每个元素加一玩。但是为了使得游戏不这么无聊,shy加一以后会给每个元素模m,这样子字典序最小的序列就会变了,生活就变得有趣。
很显然这样子加m次以后,序列会变成原来的样子。所以现在shy想知道,在他没有加一前,加一时,加二时,….,加m-1时字典序最小的序列的第k(和上面的k没有关系)个元素分别是几。


数据范围:

对于30%的数据,1≤n,m≤100;
对于100%的数据,1≤n,m≤50000, 1≤k≤n, 0≤a[i]< m.


题解:
1.字符串哈希做法

设ans[k]数组表示执行k次操作后的答案(字典序第i的数)。
    首先可以得出:

  • 当没有新加值满足%m==1时,ans[i]=ans[i-1]+1
  • 当有新加值满足%m==1时,需要更新字典序,但只需要加一个tag,再取出所有符合条件的数比较字典序
  • 在这个操作中,如果直接比较,复杂度就炸了
  • 对于很多要执行数组比较的题目,其实都可以联想到哈希表求前缀和,这样就可以直接比较啦。
  • 对于只有0-9的数组来说,单哈希太窒息了,我们要用到双哈希取模数。
  • 因为是循环的,一旦超出n的范围,处理比较麻烦,所以我们直接取a[2n],令a[n+i]=a[i]。
  • 用哈希解决lcp问题的具体方法:每次更新,二分查找两个后缀的最长公共前缀。比较第一个不同的数字。

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define now fr+k-1
typedef long long ll;
const ll mod=1e9+473;
using namespace std;
const int N=5e4+10;
const ll ha=131,hb=313;
int n,m,k,fr,a[N<<1],ans[N];
ll p[2][N];
ll t[2][N<<1];
vector<int>g[N];

inline bool check(int<
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值