牛客网多校训练3 E Sort String(字符串哈希--数位哈希)

题意:就是给你一个串,对于第i个位置,你可以把前i个字符放到队尾形成一个新的字符串,问你最后一共有几个字符串

思路:数位哈希在现场的时候是可以过的,赛后应该是加强了数据,数位哈希的都是卡在95%,但是我们写了很久没有写出来,之前没有写过字符串哈希,只是大概了解过。所以写着很麻烦,最后也一直不怎么对,一直T,看了其他人得板子以后觉得不错,收藏一份数位哈希的板子

PS:这个题的正解是kmp求最小循环接,然后随便写写就过了,真的没想到, 沉迷数位哈希无法自拔

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+50;
typedef unsigned long long ull;
struct hash_table{
  ull seed;
  ull Hash[maxn],temp[maxn];
  void Set(ull num){
    seed=num;
  }
  void work(char *s,int n){
    temp[0]=1;
    Hash[0]=0;
    for(int i=1;i<=n;i++)temp[i]=temp[i-1]*seed;
    for(int i=1;i<=n;i++)Hash[i]=(Hash[i-1]*seed+(s[i]-'a'));
  }
  ull get(int l,int r){
  return Hash[r]-Hash[l-1]*temp[r-l+1];
  }
}h;
vector<int>v[maxn];
map<string,int>mp;
char a[maxn];


int main()
{
    scanf("%s",a+1);
    int len=strlen(a+1);
    for(int i=len+1,j=1;j<=len;j++,i++){
        a[i]=a[j];
    }
    h.Set(19260817);
    h.work(a,len*2);
    unordered_map<ull,int> mp;
    int tot=0;
    for(int i=1;i<=len;i++){
        ull tmp=h.get(i,i+len-1);
        if(!mp[tmp])mp[tmp]=++tot;
        v[mp[tmp]].push_back(i-1);
    }
    printf("%d
",tot);
    for(int i=1;i<=tot;i++){
        printf("%d",v[i].size());
        for(auto it:v[i]){
            printf(" %d",it);
        }
        puts("");
    }
    return 0;
}
/*
abab
deadbeef
*/
原文地址:https://www.cnblogs.com/lalalatianlalu/p/9375947.html