[國家集訓隊]拉拉隊訓練
阿新 • • 發佈:2018-07-04
數據 cto bre math 計算 urn write 國家 break
Manacher的題,較簡單。
先manacher一下,找到每個回文串的長度,把長度為奇數的回文串統計一下,由於manacher,每個字母只會被統計一次,就不存在重復計算。看那個數據範圍裏面巨大的K很唬人,但是復雜度和這個K關系不大。(奇醜無比堪比wwb的代碼)
//Writer : Hsz %WJMZBMR%tourist%hzwer #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <queue> #include <map> #include <set> #include <stack> #include <vector> #include <cstdlib> #include <algorithm> #define LL long long #define M(a,b) memset(a,b,sizeof a) const int inf=0x3fffffff; using std::max; using std::min; using std::sort; using std::cin; using std::cout; using std::endl; using std::vector; using std::queue; const double eps=1e-8; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } void out(int x) { int a[25],wei=0; if(x<0) putchar('-'),x=-x; for(; x; x/=10) a[++wei]=x%10; if(wei==0) { puts("0"); return; } for(int j=wei; j>=1; --j) putchar('0'+a[j]); putchar('\n'); } const int N=2000005,mod=19930726; char a[N>>1],s[N]; int len,p[N],mx,id,cnt[N]; LL n,k; void manacher() { for(int i=1; i<len; i++) { if(i<mx) p[i]=min(p[id]+id-i,p[id*2-i]); else p[i]=1; while(s[i+p[i]]==s[i-p[i]]) p[i]++; if(i+p[i]>mx) mx=i+p[i],id=i; if((p[i]-1)&1) cnt[p[i]-1]++; } } LL ksm(LL base,int z) { if(base==1)return 1; if(!z) return 1; LL res=1; while(z) { if(z&1) res*=base,res%=mod; base*=base,base%=mod; z>>=1; } return res; } int main() { cin>>n>>k; scanf("%s",a); len=n; s[0]=s[1]='!'; for(int i=0; i<len; i++) { s[i*2+2]=a[i]; s[i*2+3]='!'; } len=len*2+2; s[len]=0; manacher(); LL sum=0; LL ans=1; for(int i=n-1+(n&1); i; i-=2) { sum+=cnt[i]; if(k>=sum) { ans=(ans*ksm(i,sum))%mod; k-=sum; } else { ans=(ans*ksm(i,k))%mod; k-=sum; break; } } cout<<ans; return 0; }
[國家集訓隊]拉拉隊訓練