题解 | L、字符串

想要更多的0

https://ac.nowcoder.com/acm/contest/39114/A

L、字符串

前置知识:字符串哈希

我们判断两个十进制的数是否相等,可以如下来拆分操作: 先判断个位数是否一样,再判断十位数是否一样……最后判断最高位是否一样,如果全部一样那么这两个十进制数就是一样大的。设个位数是a,十位数是b……最后一位数是z,那么这个数的大小就是:(a* 10^0)+(b * 10^1)+……+(z * 10^n).只要这个数相等,那么这两个十进制数也是相等的。

这个其实就是字符串哈希的原理。我们可以把字符串转化成一个base进制的数,只要两个字符串转化成的数相同,那我们就认为这两个字符串是相等的。但base必须是一个质数,才能保证正确性。

问题解析

记录下s的长度为len,我们可以先把字符串s转化成一个base进制的数(这里我选的base是13331)。

然后我们可以把两个s首尾相连起来,也对它求一次字符串哈希。

因为我们把两个s首尾相连了,这样把前k个字符放到最后面的操作就变成了区间[k,k+len-1]的字符串。我们只要用前缀和求[k,k+len-1]的字符串哈希值,判断和s的哈希值是否一样,我们就能知道这两个字符串是否相等了。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>

//#pragma GCC optimize(3)

#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 1e7 + 50, MOD = 1e11 + 3;
int p=99971,base=13331;
int qpow(int a, int b)
{
    int res = 1;
    while (b)
    {
        if (b & 1)res = (1LL) * res * a % MOD;
        b >>= 1;
        a = (1LL) * a * a % MOD;
    }
    return res;
}

//获取l~r这一段字符串的字符串哈希值
ull get_hash(vector<ull>&v,int l,int r,vector<ull>&bpow)
{
    ull t=v[l-1]*bpow[r-l+1];
    return (v[r]-t);
}

void solve()
{
    int n;
    string s;
    cin >> n >> s;
    string str=s+s;
    int m=str.size();
    vector<ull>v(m+1),bpow(m+1,1);
    ull res=0;
    //初始化字符串哈希值
    for(int i=1;i<=m;i++)
    {
        res=(res*base+str[i-1]);
        v[i]=res;
        bpow[i]=bpow[i-1]*base;
    }
    int k=1,cnt=0;
    //1到n部分的字符串就是原本的字符串s
    ull y=get_hash(v, 1, n, bpow);
    while(k<=n)
    {
        
        ull x=get_hash(v, k+1, k+n, bpow);
        //两个字符串哈希值相等,则这两个字符串相等
        if(x==y)cnt++;
        k++;
    }
    cout<<cnt<<endl;
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t = 1;
    //cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
全部评论

相关推荐

阿武同学:基本信息保留前面三行,其他的可以全部删掉,邮箱最重要的你没写,主修课程精简到8个以内,实习里面2/3/4都是水内容的,非要写的话建议两到三句话,项目经历排版优化下,自我评价缩到三行
点赞 评论 收藏
分享
真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务