CF240F TorCoder
题面翻译
给定一个长为\(n\)的由a到z组成的字符串,有\(m\)次操作,每次操作将\([l,r]\)这些位置的字符进行重排,得到字典序最小的回文字符串,如果无法操作就不进行。
求\(m\)次操作后的字符串。
\(n,m<=100000\)
样例 #1
样例输入 #1
7 2
aabcbaa
1 3
5 7
样例输出 #1
abacaba
样例 #2
样例输入 #2
3 2
abc
1 2
2 3
样例输出 #2
abc
分析
首先考虑如何判断回文,对于一个字符串,如果字符数量为奇数的总数大于 \(1\),进行操作则不能成为一个回文串。
那么要让回文串的字典序最小,则直接前半部分按照字典序排序来填就好了。
考虑维护 \(26\) 个线段树,每个线段树维护区间一个字母出现的个数。
对于区间修改,如果能变成回文串,则先把区间内的字符先删去,再重新排一遍即可。
最后字符串每个位置单点查询就好了。
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c&15),c=getchar();
return x*f;
}
int n,m,tag[30][100005<<2],res[30],sum[30][100005<<2];
char s[100005];
void pushup(int num,int let){sum[let][num]=sum[let][num<<1]+sum[let][num<<1|1];}
void pushdown(int num,int l,int r,int let){
if(tag[let][num]==-1)return;
int mid=l+r>>1;
tag[let][num<<1]=tag[let][num<<1|1]=tag[let][num];
sum[let][num<<1]=(mid-l+1)*tag[let][num];
sum[let][num<<1|1]=(r-mid)*tag[let][num];
tag[let][num]=-1;
}
inline void build(int l,int r,int num,int let){
tag[let][num]=-1;
if(l==r){
sum[let][num]=(s[l]-'a'+1==let);
return;
}
int mid=l+r>>1;
build(l,mid,num<<1,let),build(mid+1,r,num<<1|1,let);
pushup(num,let);
}
inline void update(int l,int r,int num,int x,int y,int let,int opt){
if(x>r||y<l)return;
if(x<=l&&r<=y){
tag[let][num]=opt,sum[let][num]=(r-l+1)*opt;
return;
}
pushdown(num,l,r,let);
int mid=l+r>>1;
update(l,mid,num<<1,x,y,let,opt),update(mid+1,r,num<<1|1,x,y,let,opt);
pushup(num,let);
}
inline int query(int l,int r,int num,int x,int y,int let){
if(x>r||y<l)return 0;
if(x<=l&&r<=y)return sum[let][num];
pushdown(num,l,r,let);
int mid=l+r>>1;
return query(l,mid,num<<1,x,y,let)+query(mid+1,r,num<<1|1,x,y,let);
}
int main(){
n=read(),m=read();cin>>s+1;
for(int i=1;i<=26;i++)build(1,n,1,i);
for(int i=1;i<=m;i++){
int x=read(),y=read(),cnt=0,let=0;
for(int j=1;j<=26;j++){
res[j]=query(1,n,1,x,y,j);
cnt+=(res[j]&1),let=(res[j]&1?j:let);
}
if(cnt>1)continue;
for(int j=1;j<=26;j++)update(1,n,1,x,y,j,0);
if(cnt)--res[let],update(1,n,1,x+y>>1,x+y>>1,let,1);
for(int j=1;j<=26;j++){
if(res[j]){
update(1,n,1,x,x+(res[j]>>1)-1,j,1);
x+=(res[j]>>1);
update(1,n,1,y-(res[j]>>1)+1,y,j,1);
y-=(res[j]>>1);
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=26;j++){
if(query(1,n,1,i,i,j))putchar('a'+j-1);
}
}
return 0;
}

浙公网安备 33010602011771号