线段树
题目名称有意思- -
用线段树维护区间各个字母出现次数即可。 然后做回文串就贪心从小往大放。
#include<cstdio>
#include<cstring>
#define N 100005
#define A 27
using namespace std;
namespace runzhe2000
{
char str[N];
int v[A];
struct seg
{
int v[A], lazy;
}t[N<<2];
void pushup(int x)
{
for(int i = 0; i < A; i++)
t[x].v[i] = t[x<<1].v[i] + t[x<<1|1].v[i];
}
void pushdown(int x, int l, int r)
{
if(t[x].lazy == -1) return; int mid = (l+r)>>1;
t[x<<1].lazy = t[x<<1|1].lazy = t[x].lazy;
memset(t[x<<1].v, 0, sizeof t[x<<1].v);
memset(t[x<<1|1].v, 0, sizeof t[x<<1|1].v);
t[x<<1].v[t[x].lazy] = mid-l+1;
t[x<<1|1].v[t[x].lazy] = r-mid;
t[x].lazy = -1;
}
void query(int x, int l, int r, int ql, int qr)
{
if(ql <= l && r <= qr) {for(int i = 0; i < A; i++) v[i] += t[x].v[i]; return;}
pushdown(x,l,r);
int mid = (l+r)>>1;
if(ql <= mid) query(x<<1,l,mid,ql,qr);
if(mid < qr) query(x<<1|1,mid+1,r,ql,qr);
}
void modi(int x, int l, int r, int ql, int qr, int v)
{
if(ql <= l && r <= qr)
{
memset(t[x].v, 0, sizeof t[x].v);
t[x].v[v] = r-l+1; t[x].lazy = v;
return;
}
pushdown(x,l,r);
int mid = (l+r)>>1;
if(ql <= mid) modi(x<<1,l,mid,ql,qr,v);
if(mid < qr) modi(x<<1|1,mid+1,r,ql,qr,v);
pushup(x);
}
void build(int x, int l, int r)
{
t[x].lazy = -1;
if(l == r)
{
memset(t[x].v, 0, sizeof t[x].v);
t[x].v[str[l] - 'a'] ++; return;
}
int mid = (l+r)>>1;
build(x<<1,l,mid); build(x<<1|1,mid+1,r);
pushup(x);
}
void main()
{
int n, m; scanf("%d%d",&n,&m);
scanf("%s",str+1);
build(1,1,n);
for(int l, r; m--; )
{
scanf("%d%d",&l,&r);
memset(v,0,sizeof v);
query(1,1,n,l,r);
int oddcnt = 0;
for(int i = 0; i < A; i++)
if(v[i]&1) oddcnt++;
if((r-l+1)&1)// odd
{
if(oddcnt != 1) continue;
}
else
{
if(oddcnt) continue;
}
for(int i = 0; i < A; i++)
{
if(v[i])
modi(1,1,n,l,l+v[i]/2-1,i), l += v[i]/2,
modi(1,1,n,r-v[i]/2+1,r,i), r -= v[i]/2;
}
for(int i = 0; i < A; i++)
if(v[i] & 1)
modi(1,1,n,l,r,i);
}
for(int i = 1; i <= n; i++)
{
memset(v,0,sizeof v);
query(1,1,n,i,i);
for(int i = 0; i < A; i++)
if(v[i]) {printf("%c",i+'a'); break;}
}
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
runzhe2000::main();
}