题意:就是给你一个串,对于第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 */