TorCoder
26棵线段树
- 建树,对于每个字符在响应字母的位置上进行修改数量
- 对于\([l,r]\)的重排,对26个字母进行区间查询出现的数量,判断是否可以组成,如果可以组成,将\([l,r]\)出现过字母的区间[l,r]赋值为0,然后根据字典序顺序对进行区间赋值操作
- \(m\)次操作后,对每个位置查询是哪个字母然后输出即可
细节见代码
// LUOGU_RID: 105747850
// AC one more times
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define endl '\n'
#define all(x) (x).begin(), (x).end()
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<long long,long long> PLL;
const int mod = 1e9+7;
const int N = 1e5+10;
struct segtree
{
int s[N*4],sz[N*4],tag[N*4];
void update(int id)
{
s[id]=s[id*2]+s[id*2+1];
sz[id]=sz[id*2]+sz[id*2+1];
}
void settag(int id,int t)
{
tag[id]=t;
if(t==0)
s[id]=0;
else if(t==1)
s[id]=sz[id];
}
void pushdown(int id)
{
if(tag[id]!=-1)
settag(id*2,tag[id]),
settag(id*2+1,tag[id]);
tag[id]=-1;
}
void build(int id,int l,int r)
{
sz[id]=r-l+1;
if(l==r)
{
s[id]=0;
return;
}
int mid=(l+r)>>1;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
update(id);
}
void modify(int id,int l,int r,int ql,int qr,int t)
{
if(ql==l&&qr==r)
{
settag(id,t);
return;
}
pushdown(id);
int mid=(l+r)>>1;
if(qr<=mid)
modify(id*2,l,mid,ql,qr,t);
else if(ql>mid)
modify(id*2+1,mid+1,r,ql,qr,t);
else
modify(id*2,l,mid,ql,mid,t),
modify(id*2+1,mid+1,r,mid+1,qr,t);
update(id);
}
int query(int id,int l,int r,int ql,int qr)
{
//cout<<l<<" "<<r<<" "<<ql<<" "<<qr<<endl;
if(ql==l&&r==qr)
{
return s[id];
}
pushdown(id);
int mid=(l+r)>>1;
if(qr<=mid)
return query(id*2,l,mid,ql,qr);
else if(ql>mid)
return query(id*2+1,mid+1,r,ql,qr);
else
return query(id*2,l,mid,ql,mid)+
query(id*2+1,mid+1,r,mid+1,qr);
}
}seg[27];
int op[27];
void solve()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n,q;
cin>>n>>q;
for(int i=1;i<=26;i++)
seg[i].build(1,1,n);
for(int i=1;i<=n;i++)
{
char c; cin>>c;
seg[c-'a'+1].modify(1,1,n,i,i,1);
}
// cout<<"-----------------\n"<<endl;
// for(int i=1;i<=n;i++)
// {
// cout<<"i : "<<i<<endl;
// for(int j=1;j<=26;j++)
// {
// cout<<char('a'+j-1)<<" : "<<seg[j].query(1,1,n,i,i)<<endl;
// }
// }
while(q--)
{
int l,r; cin>>l>>r;
memset(op,0,sizeof op);
for(int i=1;i<=26;i++)
op[i]=seg[i].query(1,1,n,l,r);
int ji=0,flag=0;
for(int i=1;i<=26;i++)
if(op[i]%2==1)
ji++,flag=i;
if(ji>=2) continue;
for(int i=1;i<=26;i++)
seg[i].modify(1,1,n,l,r,0);
int m=(l+r)>>1;
if(ji!=0)
seg[flag].modify(1,1,n,m,m,1),
op[flag]--;
int st=l,ed=r;
for(int i=1;i<=26;i++)
{
if(op[i]==0) continue;
int cnt=op[i]/2;
seg[i].modify(1,1,n,st,st+cnt-1,1);
seg[i].modify(1,1,n,ed-cnt+1,ed,1);
st+=cnt,ed-=cnt;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=26;j++)
if(seg[j].query(1,1,n,i,i)==1)
cout<<char('a'-1+j);
cout<<endl;
}
int main()
{
std::ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr);
int TC = 1;
//cin >> TC;
for(int tc = 1; tc <= TC; tc++)
{
//cout << "Case #" << tc << ": ";
solve();
}
return 0;
}
本文来自博客园,作者:magicat,转载请注明原文链接:https://www.cnblogs.com/magicat/p/17282595.html
浙公网安备 33010602011771号