四个月前,小 R 在一个荒岛上发现了神秘的巨石阵,她惊奇地发现这个巨石阵充满着魔力。于是自荒岛之旅结束后,她就一直在思考着巨石阵充满魔力的原因。她现在要开始她的魔法实验,以验证她的结论。
题目描述
由于小 R 不想花费精力取搬运巨石,她到魔法商店中购买了大量与巨石有类似魔法作用的魔法宝石,宝石也可以像巨石那样形成宝石阵。宝石一共有 26 种,方便起见,我们按照价格从低到高将每种宝石分别标号为 a,b,c,⋯,x,y,z,我们将一个宝石阵用对应位种类的标号表示成一个小写字母字符串。
小 R 经过这四个月的思考,认为巨石阵的魔力丰盈,与一种叫图腾力量的东西有关。具体而言,对于一个长度为 n 的巨石阵,我们可以将其抽象为一个长度为 n 的序列 s1,s2,⋯,sn,每存在一个 1≤i≤n−1,满足第 1∼i 个巨石形成的巨石阵和第 n−i+1∼n 个巨石形成的巨石阵完全一致,即 ∀1≤j≤i,sj=sn−i+j,则这个巨石阵就会产生若干单位的图腾力量,小 R 称这个现象为 i 的神秘化。由于每个这样的 i 产生的图腾力量相差甚微,所以小 R 直接规定每个这样的 i 会产生 1 个单位的图腾力量。
只不过图腾力量如果过于丰富,巨石阵会变得不稳定,小 R 认为这是不好的,所以她要在满足一些限制后让这个宝石阵的图腾力量最小,这样子这个巨石阵是最稳定的。小 R 推测这些结论在宝石阵上也是适用的。
现在小 R 要制作 T 个宝石阵,第 i 的宝石阵长度为 ni。同时还会给定一个大小为 ki 的序列 li,1,li,2,⋯,li,ki,对于每个 1≤j≤ki,小 R 要满足这个宝石阵会出现 li,j 的神秘化这个现象,并且让其最稳定。为了考虑价格,小 R 还要让这个宝石阵对应的字符串字典序最小。
#include<bits/stdc++.h> #define il inline #define S std::string #define V std::vector<int> #define H(x) (x).back() #define pb push_back #define qb pop_back constint N=2e5+5;
int tt,n,m,p[N]; V B; V::iterator I;
il intgcd(int a,int b){return b?gcd(b,a%b):a;}
il intKMP(const S &s) { int i,j=-1,n=s.size(); for (p[0]=-1,i=0; i<n; p[++i]=++j) for ( ; ~j&&s[j]!=s[i]; j=p[j]); return p[n]; }
il S sol(int n,V &B) { if (!B.size()) return n<2?"a":S(n-1,'a')+"b"; int i,m=B.size(),X=H(B),T=n-X; S r; for (i=m-1; ~i&&H(B)>=T; i--,B.qb()) T=gcd(T,n-H(B)); if (X=n-T,T<=X) { if (i=n%T) { I=std::lower_bound(B.begin(),B.end(),i); if (I==B.end()||*I!=i) B.insert(I,i); } for (r=sol(i+=T,B); i<n; i+=T) r+=r.substr(i-T); } else { B.qb(),r=sol(X,B)+S(T-X,'a'); if (KMP(r+=r.substr(0,X))!=X) r[T-1]='b'; } return r; }
std::ios::sync_with_stdio(0),std::cin.tie(NULL); std::cin>>tt; int i,x; while (tt--) { std::cin>>n>>m,B.clear(); while (m--) std::cin>>x,B.pb(x); std::cout<<sol(n,B)<<'\n'; } return0; }