[bzoj2160]拉拉队排练

神犇曰:“这道题不就是manacher裸题么,随便切一切吧”

我:“manacher是个啥。。。我只会hash啊。。”

看完manacher教程后:嗯?这都是个卵啊。。我去写hash吧。。

于是hash的pow数组写挂了。。。一直在WA。。。

终于A掉了。。

正着hash一遍然后反着hash一遍,最后暴力二分就ok。。就酱紫。。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <queue>
 7 #include <string>
 8 #include <vector>
 9 using namespace std;
10 
11 const int MOD=19930726;
12 const int N=2000000;
13 
14 
15 typedef unsigned long long int ull;
16 
17 int n,f[N];
18 char str[N];
19 ull h1[N],h2[N],p[N]={1};
20 long long ans=1,k,v[N];
21 
22 ull mul(ull a,ull b){
23     ull t=1;
24     while(b){
25         if(b&1)t=(t*a)%MOD;
26         a=(a*a)%MOD;
27         b>>=1;
28     }
29     return t;
30 }
31 
32 int main(){
33     scanf("%d%lld",&n,&k);
34     scanf("%s",str+1);
35     for(int i=1;i<=n;i++)p[i]=p[i-1]*10007;
36     for(int i=1;i<=n;i++)h1[i]=h1[i-1]+str[i]*p[i-1];
37     for(int i=n;i>=1;i--)h2[i]=h2[i+1]+str[i]*p[n-i];
38 
39     for(int i=1;i<=n;i++){
40         f[i]=1;
41         for(int l=1,r=min(i-1,n-i);l<=r;){
42             int mid=(l+r)>>1;
43             /*
44                 s1: i-mid~i-1
45                 s2: i+1~i+mid
46             */
47             if((h1[i-1]-h1[i-mid-1])*p[n-i-mid]==(h2[i+1]-h2[i+mid+1])*p[i-mid-1]){
48                 l=mid+1;
49                 f[i]=mid*2+1;
50             }else{
51                 r=mid-1;
52             }
53         }
54     }
55 
56     for(int i=1;i<=n;i++)v[f[i]]++;
57     for(int i=n;i>=1;i--){
58         (ans*=mul(i,min(v[i],k)))%=MOD;
59         k-=v[i];
60         if(i!=1)v[i-2]+=v[i];
61         if(k<=0)break;
62     }
63     printf("%lld\n",ans);
64 }
View Code

 

posted @ 2017-01-27 14:08  KingSann  阅读(113)  评论(0编辑  收藏  举报