Codeforces 240 F. TorCoder
3 seconds
256 megabytes
input.txt
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.
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.
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.
7 2
aabcbaa
1 3
5 7
abacaba
3 2
abc
1 2
2 3
abc
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的更多相关文章
- Codeforces 959 F. Mahmoud and Ehab and yet another xor task
\(>Codeforces\space959 F. Mahmoud\ and\ Ehab\ and\ yet\ another\ xor\ task<\) 题目大意 : 给出一个长度为 \ ...
- Codeforces 835 F. Roads in the Kingdom
\(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...
- Codeforces 731 F. Video Cards(前缀和)
Codeforces 731 F. Video Cards 题目大意:给一组数,从中选一个数作lead,要求其他所有数减少为其倍数,再求和.问所求和的最大值. 思路:统计每个数字出现的个数,再做前缀和 ...
- Codeforces 797 F Mice and Holes
http://codeforces.com/problemset/problem/797/F F. Mice and Holes time limit per test 1.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 ...
- Codeforces 379 F. New Year Tree
\(>Codeforces \space 379 F. New Year Tree<\) 题目大意 : 有一棵有 \(4\) 个节点个树,有连边 \((1,2) (1,3) (1,4)\) ...
- Codeforces 538 F. A Heap of Heaps
\(>Codeforces \space 538 F. A Heap of Heaps<\) 题目大意 :给出 \(n\) 个点,编号为 \(1 - n\) ,每个点有点权,将这些点构建成 ...
- codeforces 825F F. String Compression dp+kmp找字符串的最小循环节
/** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: d ...
- [codeforces 618 F] Double Knapsack (抽屉原理)
题目链接:http://codeforces.com/contest/618/problem/F 题目: 题目大意: 有两个大小为 N 的可重集 A, B, 每个元素都在 1 到 N 之间. 分别找出 ...
随机推荐
- [APIO2015]八邻旁之桥
题面在这里 sol 这是一个\(Splay\)的题解 首先,如果一个人的家和办公室在同一侧,我们可以直接预处理; 如果不在同一侧,也可以加上1(当然要过桥啦) 当k==1时 我们设桥的位置为\(pos ...
- PHP之工厂方法模式(三)
定义 定义一个用于创建对象的接口(抽象工厂类),让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类(抽象工厂类的子类). 工厂方法模式是简单工厂模式的进一步抽象和推广.在简单工厂 ...
- Word 2007 封面、目录和正文页码单独设置
word 2007 生成目录比较简单,即使不会,也可以百度,很快就能弄好.现在有如下需求: 1.封面去掉页码 2.目录页码从1开始,页码在页脚底部中间位置,格式为[1] 3.正文也从1开始,页码在页脚 ...
- 安装anaconda与tensorflow
在安装Anaconda之前,有的已经安装过一个Python版本了,但是又不想删除这个Python版本,该怎么办呢? 安装anaconda与tensorflow一条龙 jupyter notebook ...
- 集合中存的是引用,分析一道容易混淆的Java面试题
我们自定义的类是以引用的形式放入集合,如果使用不当,会引发非常隐蔽的错误.就拿我经常问到的一个面试题来说明这个知识点. 第一步,我们定义一个Car类型的类,其中只有一个int类型id属性. 第二步,创 ...
- git 使用方式
一.常用操作命令 1.初始化操作 git config --global user.name '<name>' # 设置提交者名称 git config --global user.ema ...
- 【阿里聚安全·安全周刊】500万台Android设备受感染|YouTube封杀枪支组装视频
本周的七个关键词: 500万Android 设备受感染丨 黑客将矛头指向无线传输协议 丨 YouTube封杀枪支视频 丨 AMD将发布补丁 丨 Gooligan Android 僵尸网络 丨 N ...
- linux 下后台运行python脚本
这两天要在服务器端一直运行一个Python脚本,当然就想到了在命令后面加&符号 $ python /data/python/server.py >python.log &说明: ...
- leetCode:461 汉明距离
汉明距离 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 思路: 当看到"对应二进制位不同的位置的数目"这 ...
- 设计模式之观察者(OBSERVER)模式
定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. Observer模式描述了如何建立这种关系.这一模式中的关键对象是目标(subject ...