Tsinsen 拉拉队排练

Posted 大奕哥&VANE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tsinsen 拉拉队排练相关的知识,希望对你有一定的参考价值。

建回文树,然后判断长度奇偶性,统计下来排序即可。

题目链接:http://www.tsinsen.com/ViewGProblem.page?gpid=A1255

By:大奕哥

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e6+5;
  4 const int M=26;
  5 const int mod=19930726;
  6 typedef long long ll;
  7 ll qmod(ll a,ll b)
  8 {
  9     ll ans=1;
 10     while(b){
 11         if(b&1)ans=ans*a%mod;
 12         b>>=1;a=a*a%mod;
 13     }
 14     return ans;
 15 }
 16 struct good{
 17     int l,n;
 18     bool operator<(const good &b)const{
 19         return l>b.l;
 20     }
 21 }a[N];
 22 struct Palindromic_Tree{
 23     int nex[N][M];
 24     int fail[N];
 25     int cnt[N];
 26     int num[N];
 27     int len[N];
 28     int S[N];
 29     int last;
 30     int n,m;
 31     int p;
 32     
 33     int newnode(int l)
 34     {
 35         for(int i=0;i<M;++i)nex[p][i]=0;
 36         cnt[p]=0;
 37         num[p]=0;
 38         len[p]=l;
 39         return p++;
 40     }
 41     
 42     void init()
 43     {
 44         p=0;
 45         newnode(0);
 46         newnode(-1);
 47         last=0;
 48         n=0;
 49         S[n]=-1;
 50         fail[0]=1;
 51     }
 52     
 53     int get_fail(int x){
 54         while(S[n-len[x]-1]!=S[n])x=fail[x];
 55         return x;
 56     }
 57     
 58     void add(int c){
 59         c-=a;
 60         S[++n]=c;
 61         int cur=get_fail(last);
 62         if(!nex[cur][c]){
 63             int now=newnode(len[cur]+2);
 64             fail[now]=nex[get_fail(fail[cur])][c];
 65             nex[cur][c]=now;
 66             num[now]=num[fail[now]]+1;
 67         }
 68         last=nex[cur][c];
 69         cnt[last]++;
 70     }
 71     
 72     void count(){
 73         for(int i=p-1;i>=0;--i)cnt[fail[i]]+=cnt[i];
 74         for(int i=p-1;i>=2;--i)
 75         {
 76             if(len[i]%2)a[++m].l=len[i],a[m].n=cnt[i];
 77         }
 78     }
 79     
 80     void solve(long long k)
 81     {
 82         sort(a+1,a+1+m);
 83         long long ans=1;
 84         for(int i=1;i<=m&&k;++i)
 85         {
 86             if(a[i].n<=k){
 87                 ans=ans*qmod(a[i].l,a[i].n)%mod;
 88                 k-=a[i].n;
 89             }
 90             else{
 91                 ans=ans*qmod(a[i].l,k)%mod;k=0;
 92             }
 93         }
 94         if(k)puts("-1");
 95         else printf("%lld\n",ans);
 96     }
 97 }T;
 98 char s[N];
 99 int l[N];
100 void solve(int n,long long k)
101 {
102     T.init();int ans=0;
103     for(int i=0;i<n;++i)
104     {
105         T.add(s[i]);
106     }
107     T.count();
108     T.solve(k);
109 }
110 int main()
111 {
112     int n;long long k;
113     scanf("%d%lld%s",&n,&k,s);
114     solve(n,k);
115     return 0;
116 }

 

以上是关于Tsinsen 拉拉队排练的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ2160]拉拉队排练

BZOJ 2160 拉拉队排练

BZOJ2160:[国家集训队2011]拉拉队排练

拉拉队排练

BZOJ2160拉拉队排练(回文树)

题解报告——拉拉队排练