考虑bi=0的特殊点考虑b_i=0的特殊点考虑bi=0的特殊点
bi=0的点一定是当前字母最大的,否则会和更大的字母产生贡献b_i=0的点一定是当前字母最大的,否则会和更大的字母产生贡献bi=0的点一定是当前字母最大的,否则会和更大的字母产生贡献
所以第一步,用最大且足够数目的字母去填充所有bi=0,标记填过所以第一步,用最大且足够数目的字母去填充所有b_i=0,标记填过所以第一步,用最大且足够数目的字母去填充所有bi=0,标记填过
那么其余没填过的都比这些字母小,所以对其余的bi修改那么其余没填过的都比这些字母小,所以对其余的b_i修改那么其余没填过的都比这些字母小,所以对其余的bi修改
怎么修改?比如bi=0且没被标记的点位置是num怎么修改?比如b_i=0且没被标记的点位置是num怎么修改?比如bi=0且没被标记的点位置是num
那么对于所有的bj!=0,bj=bj−abs(num−j),也就是减掉num对j的影响那么对于所有的b_j!=0,b_j=b_j-abs(num-j),也就是减掉num对j的影响那么对于所有的bj!=0,bj=bj−abs(num−j),也就是减掉num对j的影响
修改后,又有一些没标记的bi变成0,那么这些点是余下点中最大的修改后,又有一些没标记的b_i变成0,那么这些点是余下点中最大的修改后,又有一些没标记的bi变成0,那么这些点是余下点中最大的
重复上面的步骤即可完成步骤重复上面的步骤即可完成步骤重复上面的步骤即可完成步骤
#include <bits/stdc++.h>
using namespace std;
const int maxn=1299;
char a[maxn],ans[maxn];
int shu[27],vis[maxn],m,b[maxn];
int main()
{
int t,n;
cin>>t;
while(t--)
{
memset(shu,0,sizeof(shu));
cin>>(a+1)>>m;
for(int i=1;i<=m;i++) cin>>b[i];
for(int i=1;i<=strlen(a+1);i++)
shu[a[i]-'a'+1]++;
int num=26,da=0;
while(1)
{
int zero=0,k;
for(int i=1;i<=m;i++)
if(b[i]==0&&vis[i]==0) zero++;
for(int i=num;i>=1;i--)
if(shu[i]>=zero)
{ k=i;break;}
int cc=0,he=0;
for(int i=1;i<=m;i++)
{
if(b[i]==0&&vis[i]==0)//当前最大的字母
{
vis[i]=1;da++;
ans[i]=char(k+'a'-1);
for(int j=1;j<i;j++)
if(b[j]) b[j]-=(i-j);//减去i字母后面的影响
cc++,he+=i;
}
else if(b[i])
b[i]=b[i]-(cc*i-he);//减去i字母前面的影响
}
num=k-1;//找下一个字母
if(da==m) break;
}
for(int i=1;i<=m;i++) cout<<ans[i];
cout<<endl;
for(int i=1;i<=m;i++) vis[i]=0;
}
}