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 之间. 分别找出 ...
随机推荐
- 剑指offer-(19)顺时针打印矩阵
题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2, ...
- c#抽取pdf文档标题(4)——机器学习以及决策树
我的一位同事告诉我,pdf抽取标题,用机器学习可以完美解决问题,抽取的准确率比较高.于是,我看了一些资料,就动起手来,实践了下. 我主要是根据以往历史块的特征生成一个决策树,然后利用这棵决策树,去判断 ...
- java ---日期的格式化
import java.util.Date; import java.util.Scanner; import java.text.SimpleDateFormat; import java.util ...
- Lintcode248 Count of Smaller Number solution 题解
[题目描述] Give you an integer array (index from 0 to n-1, where n is the size of this array, value from ...
- oc 与 js交互之vue.js
- .vue.js 调用oc的方法并传值 vue.js 组件中调用方法: methods: { gotoDetail(item){ //此方法需要在移动端实现,这里可以加入判断 ...
- Batch update returned unexpected row count from update [0] 异常处理
在one-to-many时遇到此异常,本以为是配置出错.在使用s标签开启debug模式,并在struts2主配置文件中添加异常映射,再次提交表单后得到以下异常详情. org.springframewo ...
- Linux最佳的云存储服务分析
什么样的云服务才适合作为 Linux 下的存储服务?兄弟连www.itxdl.cn来帮大家分析一下! 大量的免费空间.毕竟,个人用户无法支付每月的巨额款项. 原生的 Linux 客户端.以便你能够方便 ...
- 面向服务的体系架构 SOA(三) --- Zookeeper API、zkClient API的使用
zookeeper简单介绍及API使用 1.1 zookeeper简介 zookeeper是一个针对大型分布式系统的可靠的协调系统,提供的功能包括配置维护.名字服务.分布式同步.组服务等.zookee ...
- 二分查找(Java实现)
二分查找:递归实现 public class BinarySearch { /** * @param arr 代查找的数组,需要有序 * @param left 查找区间的左界限 * @param r ...
- Django基本命令
下载Django pip3 install django #默认下载最新版 pip3 install django==1.11.1 #手动选择版本 创建Django项目 格式:django-admin ...