Codeforces Round #145 (Div. 1) 240F TorCoder

来源:互联网 发布:不干胶贴纸打印软件 编辑:程序博客网 时间:2024/05/21 06:02

题意: 给一个字符串,有m次操作。每次操作子串[l,r],如果子串能变成回文就把它变成字典序最小的回文,否则不操作。输出最后的字符串。


思路: 如果你知道一个字符串有几个a组成几个b组成...,并且它能够组成回文,那么你就能迅速写出它字典序最小的回文(a先放两边再b这样下去)。所以我们只要用线段树统计好字符串里26个字母的个数就能得出回文,并且按这个回文更新线段树。


代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <climits>#include <numeric>#include <vector>#define N 100010int n;char buf[N];struct segment{int l,r,mark,cnt[26];segment(){memset(cnt,0,sizeof(cnt));mark=-1;}};class segTree{#define lson rt<<1#define rson rt<<1|1#define rtl seg[rt].l#define rtr seg[rt].rprivate:segment seg[N<<2];public:void setValue(int c,int rt){memset(seg[rt].cnt,0,sizeof(seg[rt].cnt));seg[rt].cnt[c]=rtr-rtl+1;}void pushup(int rt){for(int i=0;i<26;i++)seg[rt].cnt[i]=seg[lson].cnt[i]+seg[rson].cnt[i];}void pushdown(int rt){if(seg[rt].mark!=-1){setValue(seg[rt].mark,lson);setValue(seg[rt].mark,rson);seg[lson].mark=seg[rt].mark;seg[rson].mark=seg[rt].mark;seg[rt].mark=-1;}}void update(int c,int L,int R,int rt){if(L<=rtl && rtr <=R){seg[rt].mark=c;setValue(c,rt);return ;}pushdown(rt);int mid=(rtl+rtr)>>1;if(L<=mid) update(c,L,R,lson);if(R>mid) update(c,L,R,rson);pushup(rt);}void query(int cnt[],int L,int R,int rt){if(L<=rtl && rtr <=R){for(int i=0;i<26;i++)cnt[i]+=seg[rt].cnt[i];return ;}int mid=(rtl+rtr)>>1;pushdown(rt);if(L<=mid) query(cnt,L,R,lson);if(R>mid) query(cnt,L,R,rson);}void build(int l,int r,int rt){rtl=l,rtr=r;if(l==r){seg[rt].cnt[buf[l-1]-'a']=1;return ;}int mid=(l+r)>>1;build(l,mid,lson);build(mid+1,r,rson);pushup(rt);}void transform(char ans[],int rt){if(rtl==rtr){for(int i=0;i<26;i++)if(seg[rt].cnt[i]){ans[rtl-1]='a'+i;break;}return ;}pushdown(rt);transform(ans,lson);transform(ans,rson);}}T;bool check(int l,int r,int cnt[]){int i,oddsum=0;for(i=0;i<26;i++)if(cnt[i]%2) oddsum++;if(oddsum>1) return false;if(oddsum!=(r-l+1)%2) return false;return true;}void solve(int L,int R){int i,cnt[26]={0},oddpos=-1,l,r,_l,_r;T.query(cnt,L,R,1);if(!check(L,R,cnt)) return ;for(i=0;i<26;i++){if(cnt[i]%2){oddpos=i;break;}}if(oddpos!=-1) cnt[oddpos]--;l=L , _r=R;    for(i=0;i<26;i++){cnt[i]/=2;if(cnt[i]){r=cnt[i]+l-1;_l=-cnt[i]+_r+1;T.update(i,l,r,1);T.update(i,_l,_r,1);l=r+1;_r=_l-1;}}if(oddpos!=-1)T.update(oddpos,l,_r,1);}int main(){#ifdef ONLINE_JUDGEfreopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);#endifint m,l,r;scanf("%d %d",&n,&m);scanf("%s",buf);T.build(1,n,1);while(m--){scanf("%d %d",&l,&r);solve(l,r);}T.transform(buf,1);printf("%s\n",buf);return 0;}




原创粉丝点击