呀呀呀,临走10分钟刷一道水题

然而只是记一下第一次hash被卡

各种模数都被卡了...

本来想打双哈希了,后来皮了一下,模数改成了998244353,然后竟然A掉了

 

正着hash一遍,反着hash一遍

对于一个串都取正反hash值的min值,若其相同,则必然是相同串(不被卡的话)

计数用set就好了

 1 #include<bits/stdc++.h>
 2 #define ull unsigned long long
 3 using namespace std;
 4 inline int read(){
 5     int ans=0,f=1;char chr=getchar();
 6     while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();}
 7     while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
 8     return ans*f;
 9 }const int M=2e5+5,B=998244353;
10 ull f[M],ff[M],h[M];
11 int s[M],n,maxn,cnt,k[M];
12 inline void Hash(){int i;
13     for(i=1,h[0]=1;i<=n;i++) h[i]=h[i-1]*B,f[i]=f[i-1]*B+s[i];
14     for(i=n;i>=1;i--) ff[i]=ff[i+1]*B+s[i];
15 }
16 inline ull Get1(int l,int r){return f[r]-f[l-1]*h[r-l+1];}
17 inline ull Get2(int l,int r){return ff[l]-ff[r+1]*h[r-l+1];}
18 set<ull> ss;
19 inline int Calc(int k){
20     int t=0;ss.clear();
21     for(int i=1;i+k-1<=n;i+=k){
22         ull tmp=min(Get1(i,i+k-1),Get2(i,i+k-1));
23         ss.insert(tmp);
24     }return ss.size();
25 }
26 int main(){
27     n=read();
28     for(int i=1;i<=n;i++) s[i]=read();
29     Hash();
30     for(int i=1;i<=n;i++){
31         int now=Calc(i);
32         if(now>maxn) maxn=now,cnt=0;
33         if(now==maxn)k[++cnt]=i;
34     }
35     cout<<maxn<<" "<<cnt<<endl;
36     for(int i=1;i<=cnt;i++)    cout<<k[i]<<" ";
37     return 0;
38 }