F. TorCoder
time limit per test

3 seconds

memory limit per test

256 megabytes

input

input.txt

output

output.txt

A boy named Leo doesn't miss a single TorCoder contest round. On the last TorCoder round number 100666 Leo stumbled over the following problem. He was given a string s, consisting of n lowercase English letters, and m queries. Each query is characterised by a pair of integers li, ri (1 ≤ li ≤ ri ≤ n).

We'll consider the letters in the string numbered from 1 to n from left to right, that is, s = s1s2... sn.

After each query he must swap letters with indexes from li to ri inclusive in string s so as to make substring (li, ri) a palindrome. If there are multiple such letter permutations, you should choose the one where string (li, ri) will be lexicographically minimum. If no such permutation exists, you should ignore the query (that is, not change string s).

Everybody knows that on TorCoder rounds input line and array size limits never exceed 60, so Leo solved this problem easily. Your task is to solve the problem on a little bit larger limits. Given string s and m queries, print the string that results after applying all m queries to string s.

Input

The first input line contains two integers n and m (1 ≤ n, m ≤ 105) — the string length and the number of the queries.

The second line contains string s, consisting of n lowercase Latin letters.

Each of the next m lines contains a pair of integers li, ri (1 ≤ li ≤ ri ≤ n) — a query to apply to the string.

Output

In a single line print the result of applying m queries to string s. Print the queries in the order in which they are given in the input.

Examples
input
7 2
aabcbaa
1 3
5 7
output
abacaba
input
3 2
abc
1 2
2 3
output
abc
Note

A substring (li, ri) 1 ≤ li ≤ ri ≤ n) of string s = s1s2... sn of length n is a sequence of characters slisli + 1...sri.

A string is a palindrome, if it reads the same from left to right and from right to left.

String x1x2... xp is lexicographically smaller than string y1y2... yq, if either p < q and x1 = y1, x2 = y2, ... , xp = yp, or exists such number r(r < p, r < q), that x1 = y1, x2 = y2, ... , xr = yr and xr + 1 < yr + 1.

题意:

给定一个长为n的字符串。

有m次操作,每次操作将[l,r]这些位置的字符进行重排,得到字典序最小的回文字符串,如果无法操作就不进行。

求m次操作后的字符串。

26颗线段树 维护区间 每个字母的出现次数

为了使得字典序最小,贪心的放进去。

要做的操作是:区间查询和,区间赋值为1,区间赋值为0。

做麻烦了,其实只需要一颗线段树就可以。。。

#include<cstdio>
#include<cstring>
#define N 100001
#define M N*50
using namespace std;
int cnt;
int root[],tot[],pre[],suc[];
struct node
{
int lc,rc,sum1;
bool all0,all1;
bool f0,f1;
}tr[M];
void up(int k)
{
tr[k].all0=tr[tr[k].lc].all0&tr[tr[k].rc].all0;
tr[k].all1=tr[tr[k].lc].all1&tr[tr[k].rc].all1;
tr[k].sum1=tr[tr[k].lc].sum1+tr[tr[k].rc].sum1;
}
void insert(int &k,int l,int r,int pos)
{
if(!k) k=++cnt;
tr[k].sum1++;
if(l==r)
{
tr[k].all1=true;
return;
}
int mid=l+r>>;
if(pos<=mid) insert(tr[k].lc,l,mid,pos);
else insert(tr[k].rc,mid+,r,pos);
up(k);
}
void down(int k,int l,int r)
{
if(tr[k].f0)
{
if(!tr[k].lc) tr[k].lc=++cnt;
if(!tr[k].rc) tr[k].rc=++cnt;
tr[tr[k].lc].all0=tr[tr[k].lc].f0=true;
tr[tr[k].lc].all1=tr[tr[k].lc].f1=false;
tr[tr[k].rc].all0=tr[tr[k].rc].f0=true;
tr[tr[k].rc].all1=tr[tr[k].rc].f1=false;
tr[tr[k].lc].sum1=tr[tr[k].rc].sum1=;
tr[k].f0=false;
}
else
{
if(!tr[k].lc) tr[k].lc=++cnt;
if(!tr[k].rc) tr[k].rc=++cnt;
tr[tr[k].lc].all0=tr[tr[k].lc].f0=false;
tr[tr[k].lc].all1=tr[tr[k].lc].f1=true;
tr[tr[k].rc].all0=tr[tr[k].rc].f0=false;
tr[tr[k].rc].all1=tr[tr[k].rc].f1=true;
int mid=l+r>>;
tr[tr[k].lc].sum1=mid-l+;
tr[tr[k].rc].sum1=r-mid;
tr[k].f1=false;
}
}
void change0(int k,int l,int r,int opl,int opr)
{
if(!k) k=++cnt;
if(l>=opl && r<=opr)
{
tr[k].all0=tr[k].f0=true;
tr[k].all1=tr[k].f1=false;
tr[k].sum1=;
return;
}
if(tr[k].f0 || tr[k].f1) down(k,l,r);
int mid=l+r>>;
if(opl<=mid ) change0(tr[k].lc,l,mid,opl,opr);
if(opr>mid ) change0(tr[k].rc,mid+,r,opl,opr);
up(k);
}
void change1(int &k,int l,int r,int opl,int opr)
{
if(!k) k=++cnt;
if(tr[k].all1) return;
if(l>=opl && r<=opr)
{
tr[k].all0=tr[k].f0=false;
tr[k].all1=tr[k].f1=true;
tr[k].sum1=r-l+;
return;
}
if(tr[k].f0 || tr[k].f1) down(k,l,r);
int mid=l+r>>;
if(opl<=mid ) change1(tr[k].lc,l,mid,opl,opr);
if(opr>mid ) change1(tr[k].rc,mid+,r,opl,opr);
up(k);
}
int query(int k,int l,int r,int opl,int opr)
{
if(tr[k].all0) return ;
if(l>=opl && r<=opr) return tr[k].sum1;
if(tr[k].f0 || tr[k].f1) down(k,l,r);
int mid=l+r>>,tmp=;
if(opl<=mid && tr[k].lc) tmp+=query(tr[k].lc,l,mid,opl,opr);
if(opr>mid && tr[k].rc) tmp+=query(tr[k].rc,mid+,r,opl,opr);
return tmp;
}
bool point_query(int k,int l,int r,int pos)
{
if(l==r) return tr[k].sum1;
if(tr[k].f0 || tr[k].f1) down(k,l,r);
int mid=l+r>>;
if(pos<=mid)
{
if(tr[k].lc) return point_query(tr[k].lc,l,mid,pos);
return false;
}
else
{
if(tr[k].rc) return point_query(tr[k].rc,mid+,r,pos);
return false;
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n,m; char s[N];
scanf("%d%d",&n,&m);
scanf("%s",s);
tr[].all0=true;
for(int i=;i<n;i++) insert(root[s[i]-'a'],,n,i+);
int opl,opr; bool odd,fail;
int od,mid;
while(m--)
{
scanf("%d%d",&opl,&opr);
odd=fail=false; memset(tot,,sizeof(tot)); od=-;
for(int i=;i<;i++)
{
tot[i]=query(root[i],,n,opl,opr);
if(tot[i]%)
if(!odd) odd=true,od=i,tot[i]--;
else { fail=true; break; }
}
if(fail) continue;
for(int i=;i<;i++)
if(tot[i] || od==i) change0(root[i],,n,opl,opr); pre[]=tot[];
for(int i=;i<;i++) pre[i]=pre[i-]+tot[i]; suc[]=tot[];
for(int i=;i<;i++) suc[i]=suc[i-]+tot[-i]; if(tot[]) change1(root[],,n,opl,opl+pre[]/-);
for(int i=;i<;i++)
if(tot[i]) change1(root[i],,n,opl+pre[i-]/,opl+pre[i]/-); if(odd) mid=opl+pre[]/,change1(root[od],,n,opl+pre[]/,opl+pre[]/);
else mid=opl+pre[]/-; if(tot[]) change1(root[],,n,mid+,mid+suc[]/);
for(int i=;i<;i++)
if(tot[-i]) change1(root[-i],,n,mid+suc[i-]/+,mid+suc[i]/);
/*for(int i=1;i<=n;i++)
for(int j=0;j<26;j++)
if(point_query(root[j],1,n,i))
{
putchar('a'+j);
break;
}
puts("");*/
}
for(int i=;i<=n;i++)
for(int j=;j<;j++)
if(point_query(root[j],,n,i))
{
putchar('a'+j);
break;
}
}

Codeforces 240 F. TorCoder的更多相关文章

  1. Codeforces 959 F. Mahmoud and Ehab and yet another xor task

    \(>Codeforces\space959 F. Mahmoud\ and\ Ehab\ and\ yet\ another\ xor\ task<\) 题目大意 : 给出一个长度为 \ ...

  2. Codeforces 835 F. Roads in the Kingdom

    \(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...

  3. Codeforces 731 F. Video Cards(前缀和)

    Codeforces 731 F. Video Cards 题目大意:给一组数,从中选一个数作lead,要求其他所有数减少为其倍数,再求和.问所求和的最大值. 思路:统计每个数字出现的个数,再做前缀和 ...

  4. Codeforces 797 F Mice and Holes

    http://codeforces.com/problemset/problem/797/F F. Mice and Holes time limit per test             1.5 ...

  5. Codeforces 622 F. The Sum of the k-th Powers

    \(>Codeforces \space 622\ F. The\ Sum\ of\ the\ k-th\ Powers<\) 题目大意 : 给出 \(n, k\),求 \(\sum_{i ...

  6. Codeforces 379 F. New Year Tree

    \(>Codeforces \space 379 F. New Year Tree<\) 题目大意 : 有一棵有 \(4\) 个节点个树,有连边 \((1,2) (1,3) (1,4)\) ...

  7. Codeforces 538 F. A Heap of Heaps

    \(>Codeforces \space 538 F. A Heap of Heaps<\) 题目大意 :给出 \(n\) 个点,编号为 \(1 - n\) ,每个点有点权,将这些点构建成 ...

  8. codeforces 825F F. String Compression dp+kmp找字符串的最小循环节

    /** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: d ...

  9. [codeforces 618 F] Double Knapsack (抽屉原理)

    题目链接:http://codeforces.com/contest/618/problem/F 题目: 题目大意: 有两个大小为 N 的可重集 A, B, 每个元素都在 1 到 N 之间. 分别找出 ...

随机推荐

  1. 【洛谷1131】【ZJOI2007】时态同步

    题面 题目描述 小Q在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字1,2,3-.进行标号.电路板的各个节点由若干不相交的导线相连接,且对于电路板的任何两 ...

  2. USACO08MAR Land Acquisition

    斜率优化 # include <stdio.h> # include <stdlib.h> # include <iostream> # include <s ...

  3. 踩坑系列の Oracle dbms_job简单使用

    二话不说先上代码 --创建存储过程 create or replace procedure job_truncateState is begin --此处就是要定时执行的sql execute imm ...

  4. UML 中extend和include的区别

    在UML用例图中有两种关系——包含和扩展,容易混淆,下面通过一张表来区别一下这两种关系.

  5. Django---视图

    全过程:用户填写相关数据,提交相关请求,链接到对应的视图上,在此视图上(有用户传过来的数据[就是视图要处理的数据],在视图里面对数据进行业务处理,在数据库中crub数据,然后把对应的界面和界面显示需要 ...

  6. 15.MySQL(三)

    索引类型 先创建表 mysql> CREATE TABLE test( -> id INT, -> username VARCHAR(16), -> city VARCHAR( ...

  7. python爬微信公众号前10篇历史文章(5)-JSON相关内容小结

    json - JSON encoder and decoder JSON: JavaScript object notation,是一种轻量级的数据交换格式.JSON 是 JS 对象的字符串表示法,它 ...

  8. Redis 学习相关的网站

    Redis 命令参考 http://doc.redisfans.com/ https://redis.io/commands http://www.redis.net.cn Redis教程 http: ...

  9. Git分支(3/5) -- 禁用 Fast Forward 合并

    添加一个分支, 并且换到该分支: git checkout -b add-text 然后我再index.html里面添加点文字, 并commit. 然后再修改README.md, 添加文字, comm ...

  10. python编程中的if __name__ == 'main与windows中使用多进程

    if __name__ == 'main 一个python的文件有两种使用的方法,第一是直接作为程序执行,第二是import到其他的python程序中被调用(模块重用)执行. 因此if __name_ ...