线段树统计和维护某一区间内的字母个数。。

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 strings.

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.

Sample test(s)
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.

/* ***********************************************
Author :CKboss
Created Time :2015年07月20日 星期一 07时29分48秒
File Name :CF240F_2.cpp
************************************************ */ #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map> using namespace std; const int maxn=100100; int n,m;
int sum[28][maxn<<2];
int add[maxn<<2]; /// lazy
char str[maxn];
int cs[28]; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 void cls(int rt)
{
add[rt]=-1;
for(int i=0;i<26;i++) sum[i][rt]=0;
} void push_up(int rt)
{
for(int i=0;i<26;i++)
sum[i][rt]=sum[i][rt<<1]+sum[i][rt<<1|1];
} void push_down(int l,int r,int rt)
{
if(add[rt]!=-1)
{
int m=(l+r)/2;
int id = add[rt]; cls(rt<<1); cls(rt<<1|1); add[rt<<1]=add[rt<<1|1]=add[rt];
sum[id][rt<<1]=m-l+1; sum[id][rt<<1|1]=r-m; add[rt]=-1;
}
} void build(int l,int r,int rt)
{
add[rt]=-1;
if(l==r)
{
int id=str[l]-'a';
sum[id][rt]++; add[rt]=id;
return ;
}
int m=(l+r)/2;
build(lson); build(rson);
push_up(rt);
} void query(int L,int R,int l,int r,int rt)
{ if(L<=l&&r<=R)
{
for(int i=0;i<26;i++) cs[i]+=sum[i][rt];
return ;
} push_down(l,r,rt); int m=(l+r)/2;
if(L<=m) query(L,R,lson);
if(R>m) query(L,R,rson); push_up(rt);
} void update(int id,int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
cls(rt); add[rt]=id;
sum[id][rt]=r-l+1; return ;
} push_down(l,r,rt); int m=(l+r)/2;
if(L<=m) update(id,L,R,lson);
if(R>m) update(id,L,R,rson); push_up(rt);
} char res[maxn]; void solve(int L,int R)
{
int op=-1,odd=0; memset(cs,0,sizeof(cs));
query(L,R,1,n,1);
for(int i=0;i<26;i++)
{
if(cs[i]%2) { odd++; op=i; }
if(odd>1) return ;
} int st=L,en=R;
int MID=L+(R-L+1)/2;
for(int i=0;i<26;i++)
{
if(cs[i])
{
if(cs[i]/2)
{
update(i,st,st+cs[i]/2-1,1,n,1);
update(i,en-cs[i]/2+1,en,1,n,1); st=st+cs[i]/2;
en=en-cs[i]/2;
}
if(cs[i]%2==1)
{
update(i,MID,MID,1,n,1);
}
}
}
} int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout); scanf("%d%d",&n,&m);
scanf("%s",str+1); /// build
build(1,n,1); int L,R;
while(m--)
{
scanf("%d%d",&L,&R); solve(L,R);
}
for(int i=1;i<=n;i++)
{
memset(cs,0,sizeof(cs));
query(i,i,1,n,1);
for(int j=0;j<26;j++)
if(cs[j])
{
putchar('a'+j); break;
}
}
putchar(10); return 0;
}

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

  1. Vasya and a Tree CodeForces - 1076E(线段树+dfs)

    I - Vasya and a Tree CodeForces - 1076E 其实参考完别人的思路,写完程序交上去,还是没理解啥意思..昨晚再仔细想了想.终于弄明白了(有可能不对 题意是有一棵树n个 ...

  2. Codeforces 787D. Legacy 线段树建模+最短路

    D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  3. Almost Regular Bracket Sequence CodeForces - 1095E (线段树,单点更新,区间查询维护括号序列)

    Almost Regular Bracket Sequence CodeForces - 1095E You are given a bracket sequence ss consisting of ...

  4. Sereja and Brackets CodeForces - 380C (线段树+分治思路)

    Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...

  5. CodeForces 91B Queue (线段树,区间最值)

    http://codeforces.com/problemset/problem/91/B B. Queue time limit per test: 2 seconds memory limit p ...

  6. Codeforces 343D WaterTree - 线段树, DFS序

    Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...

  7. codeforces 787D - Legacy 线段树优化建图,最短路

    题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...

  8. Subtree Minimum Query CodeForces - 893F (线段树合并+线段树动态开点)

    题目链接:https://cn.vjudge.net/problem/CodeForces-893F 题目大意:给你n个点,每一个点有权值,然后这n个点会构成一棵树,边权为1.然后有q次询问,每一次询 ...

  9. Codeforces 765F Souvenirs 线段树 + 主席树 (看题解)

    Souvenirs 我们将询问离线, 我们从左往右加元素, 如果当前的位置为 i ,用一棵线段树保存区间[x, i]的答案, 每次更新完, 遍历R位于 i 的询问更新答案. 我们先考虑最暴力的做法, ...

随机推荐

  1. RunTime.getRunTime().addShutdownHook用法

    今天在阅读Tomcat源码的时候,catalina这个类中使用了下边的代码,不是很了解,所以google了一下,然后测试下方法,Tomcat中的相关代码如下: Runtime.getRuntime() ...

  2. 1. Two Sum【easy】

    1. Two Sum[easy] Given an array of integers, return indices of the two numbers such that they add up ...

  3. discuz添加管理员,找回管理员方法

    增加创始人方法: 第一步:打开现在创始人的后台,将你所需要增加的创始人设置为管理员,并且给予后台副站长权限,这两部一定要做到位,先把这两步做完之后再做下面的! 具体设置管理员和给予后台副站长权限请查看 ...

  4. codeforces624b Making a String

      Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status De ...

  5. IOS设计模式的六大设计原则之迪米特法则(LOD,Law Of Demeter)

    定义 狭义的迪米特法则定义:也叫最少知识原则(LKP,Least Knowledge Principle).如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用.如果其中的一个类需要调用 ...

  6. iOS图片加水印效果的实现并保存至相冊

    图片加水印效果的实现并保存至相冊 实现效果如图: project下载:githubproject下载链接 代码: - (void)viewDidLoad { [super viewDidLoad]; ...

  7. Photoshop脚本之调试

    系统:mac 创建test.scpt和test.jsx command+空格,打开 脚本编辑器(applescript) 脚本编辑器打开test.scpt 输入: tell application & ...

  8. 使用nginx cache缓存网站数据实践

    Nginx本身就有缓存功能,能够缓存静态对象,比如图片.CSS.JS等内容直接缓存到本地,下次访问相同对象时,直接从缓存即可,无需访问后端静态服务器以及存储存储服务器,可以替代squid功能. 1   ...

  9. ios--后台返回信息有字符串和数字组成的,如何获取电话号码,让用户能够点击并且进行拨打?

    -(void)callPhone:(NSString*)phoneNumber{ NSString *phoneStr=[NSString stringWithFormat:@"tel:// ...

  10. Windows中安装Scrapy

    在linux中安装Scrapy只需要导入一些非python的支持包,在windows中安装Scrapy则是一波三折. 总之来说,主要分为以下几个步骤,可能由于系统问题(国内个人机子,甚至是小企业的机子 ...