1、B站视频链接:F01 最小表示法_哔哩哔哩_bilibili
题目链接:【模板】最小表示法 - 洛谷
#include <bits/stdc++.h>
using namespace std;
const int N=7e5;
int n;
int s[N];int get_min(){for(int i=1;i<=n;i++)s[n+i]=s[i];//字符串复制一倍int i=1,j=2,k=0;while(i<=n&&j<=n){for(k=0;k<n&&s[i+k]==s[j+k];k++);//相等则向后扫描s[i+k]>s[j+k]?i=i+k+1:j=j+k+1;//跳过被淘汰的那段if(i==j)j++;//相等了则让i,j其中之一向后加一位 } return min(i,j);//返回最小指针的位置
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&s[i]);int k=get_min();for(int i=0;i<n;i++){printf("%d ",s[k+i]);}return 0;
}
2、B站视频链接:F02 字符串哈希_哔哩哔哩_bilibili
题目链接:【模板】字符串哈希 - 洛谷
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
int n,m;
const int N=1000010,P=131;
char s[N];
ULL p[N],h[N];//p[i]=p^i即p的i次方,h[i]是s[1~i]的hash值//预处理hash函数的前缀和
void init(){p[0]=1,h[0]=0;for(int i=1;i<=n;i++){p[i]=p[i-1]*P;h[i]=h[i-1]*P+s[i];}
}
//计算s[l~r]的hash值,求区间和
ULL get(int l,int r){return h[r]-h[l-1]*p[r-l+1];
}
//判断两子串是否相等
bool substr(int l1,int r1,int l2,int r2){return get(l1,r1)==get(l2,r2);
}
int main(){cin>>n>>m;scanf("%s",s+1);init();while(m--){int a,b,c,d;cin>>a>>b>>c>>d;if(substr(a,b,c,d))puts("Yes");else puts("No");}return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N=10010;
int n,m;
char s[N];
typedef unsigned long long ULL;
const int P=131;
ULL h[N],ans[N];//计算每个字符串的哈希值
ULL calc(char *s,int n){h[0]=0;for(int i=1;i<=n;i++){h[i]=h[i-1]*P+s[i];}return h[n];//前缀和
}
int main(){cin>>n;for(int i=1;i<=n;i++){scanf("%s",s+1);int m=strlen(s+1);//计算字符串的长度 ans[i]=calc(s,m);}sort(ans+1,ans+n+1);//将所有哈希值排成升序,提高比较的效率 int cnt=0;for(int i=1;i<=n;i++){if(ans[i]!=ans[i-1])++cnt;}printf("%d",cnt);return 0;
}