~~~题面~~~

题解:

  观察到字母只有26个,因此考虑对这26个字母分别维护,每个线段树维护一个字母,如果一个线段树的某个叶节点有值,表示当前叶节点所在位置的字母是现在这个线段树代表的字母。

  那么对于每一个操作,我们已经知道最后排好序之后肯定是按aaaabbbbccccddd……这样的序列排下去的(有些字母可能没有),每个字母都集中在自己的区间内。

  那么我们只需要知道每个字母之前的字母有多少个,就可以知道这个字母所在区间,因此按顺序修改。

  (以下操作均视为在每个字母对应的线段树上操作)先查询a的个数,并把当前修改的区间内赋0,然后把前1~tot_a全都赋1,表示这段区间是属于a的(全都放上1)。

  记在统计当前字母之前找到的字母个数之和为tot,则每次都是把当前线段树管理的字母全都移动到tot + 1~tot + 字母个数,相当于跟修改a类似的区间操作。只不过属于这个字母的区间的开始端点是tot + 1(其实a的情况也可以视作是tot + 1,因为这个时候tot = 0)

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define LL long long
#define AC 101000
#define ac 401000 int n, m, id, tot, add, t;
int l[ac], r[ac];
char s[AC], ans[AC]; int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c -'', c = getchar();
return x;
} inline void upmin(int &a, int b)
{
if(b < a) a = b;
} inline void upmax(int &a, int b)
{
if(b > a) a = b;
} struct segament_tree{
int tree[ac], lazy[ac], id; inline void init()
{
memset(lazy, -, sizeof(lazy));
} inline void update(int x)
{
tree[x] = tree[x * ] + tree[x * + ];
} inline void pushdown(int x)
{
if(lazy[x] != -)
{
int ll = x * , rr = ll + ;
lazy[ll] = lazy[rr] = lazy[x];
if(!lazy[x]) tree[ll] = tree[rr] = ;
else
{
int mid = (l[x] + r[x]) >> ;
tree[ll] = mid - l[ll] + ;
tree[rr] = r[rr] - mid;
}
lazy[x] = -;
}
} void build(int x, int ll, int rr)
{
if(!id) l[x] = ll, r[x] = rr;
if(ll == rr)
{
if(s[ll] == id + 'a') tree[x] = ;
return ;
}
int mid = (ll + rr) >> ;
build(x * , ll, mid);
build(x * + , mid + , rr);
update(x);
} void find(int x, int ll, int rr)
{
if(!tree[x]) return ;
if(l[x] == ll && r[x] == rr){add += tree[x]; return ;}
pushdown(x);
int mid = (l[x] + r[x]) >> ;
if(rr <= mid) find(x * , ll, rr);
else if(ll > mid) find(x * + , ll, rr);
else
{
find(x * , ll, mid);
find(x * + , mid + , rr);
}
update(x);
} void change(int x, int ll, int rr)
{
if(l[x] == ll && r[x] == rr)
{
lazy[x] = t;
if(t) tree[x] = rr - ll + ;
else tree[x] = ;
return ;
}
pushdown(x);
int mid = (l[x] + r[x]) >> ;
if(rr <= mid) change(x * , ll, rr);
else if(ll > mid) change(x * + , ll, rr);
else
{
change(x * , ll, mid);
change(x * + , mid + , rr);
}
update(x);
} void get(int x)
{
if(!tree[x]) return ;
if(tree[x] == r[x] - l[x] + )
{
for(R i = l[x]; i <= r[x]; i ++) ans[i] = id + 'a';
return ;
}
pushdown(x);
if(tree[x * ]) get(x * );
if(tree[x * + ]) get(x * + );
} }T[]; void pre()
{
n = read(), m = read();
scanf("%s", s + );
for(R i = ; i < ; i ++)
T[i].id = i, T[i].init(), T[i].build(, , n);
} void check()
{
for(R i = ; i < ; i ++) T[i].get();
for(R i = ; i <= n; i ++) printf("%c", ans[i]);
printf("\n");
} void work()
{
int ll, rr, opt;
for(R i = ; i <= m; i ++)
{
// printf("%d\n", i);
ll = read(), rr = read(), opt = read(), tot = ll - ;
if(opt)
{
for(R j = ; j < ; j ++)
{
add = t = ;
T[j].find(, ll, rr);
if(!add) continue;
T[j].change(, ll, rr);
t = ;
T[j].change(, tot + , tot + add);
tot += add;
}
//check();
}
else
{
for(R j = ; j >= ; j --)
{
add = t = ;
T[j].find(, ll, rr);
if(!add) continue;
T[j].change(, ll, rr);
t = ;
T[j].change(, tot + , tot + add);
tot += add;
}
// check();
}
}
for(R i = ; i < ; i ++) T[i].get();
for(R i = ; i <= n; i ++) printf("%c", ans[i]);
printf("\n");
} int main()
{
//freopen("string6.in", "r", stdin);
pre();
work();
//fclose(stdin);
return ;
}

CF#312 558e A Simple Task的更多相关文章

  1. CF #312 E. A Simple Task 线段树

    题目链接:http://codeforces.com/problemset/problem/558/E 给一个字符串,每次对一个区间内的子串进行升序或者降序的排列,问最后字符串什么样子. 对于字符串排 ...

  2. 计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task

    E. A Simple Task Problem's Link: http://codeforces.com/problemset/problem/558/E Mean: 给定一个字符串,有q次操作, ...

  3. Codeforces 558E A Simple Task (计数排序&&线段树优化)

    题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memor ...

  4. Codeforces 558E A Simple Task(权值线段树)

    题目链接  A Simple Task 题意  给出一个小写字母序列和若干操作.每个操作为对给定区间进行升序排序或降序排序. 考虑权值线段树. 建立26棵权值线段树.每次操作的时候先把26棵线段树上的 ...

  5. Codeforces 558E A Simple Task

    题意:给定一个字符串,以及m次操作,每次操作对字符串的一个子区间进行升序或降序排序,求m次操作后的串 考虑桶排,发现线段树可以模拟桶排的过程,所以对26个字母分别建立线段树即可 #include< ...

  6. codeforces 558E A Simple Task 线段树

    题目链接 题意较为简单. 思路: 由于仅仅有26个字母,所以用26棵线段树维护就好了,比較easy. #include <iostream> #include <string> ...

  7. Codeforces 558E A Simple Task(计数排序+线段树优化)

    http://codeforces.com/problemset/problem/558/E Examples input 1 abacdabcda output 1 cbcaaaabdd input ...

  8. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树

    E. A Simple Task 题目连接: http://www.codeforces.com/contest/558/problem/E Description This task is very ...

  9. Codeforces Round #312 (Div. 2) E. A Simple Task 线段树+计数排序

    题目链接: http://codeforces.com/problemset/problem/558/E E. A Simple Task time limit per test5 secondsme ...

随机推荐

  1. struts2-01:作用域传值

    方式一.使用ServletActionContext(耦合度高,不建议使用) public String login(){ ServletActionContext.getRequest().getS ...

  2. FreeRTOS的信号量和互斥量

    1. 理解如下,言简意赅的说,信号量解决同步,互斥量解决竞争. 信号量用于同步,主要任务间和中断间同步:互斥量用于互锁,用于保护同时只能有一个任务访问的资源,为资源上一把锁. 互斥量具有优先级继承,信 ...

  3. Servlet的5种方式实现表单提交(注册小功能)

    Servlet的5种方式实现表单提交(注册小功能),后台获取表单数据   用servlet实现一个注册的小功能 ,后台获取数据. 注册页面: 注册页面代码 : <!DOCTYPE html> ...

  4. Tomcat7后台通过get接收数据处理乱码

    Tomcat7后台通过get接收数据处理乱码 //因为tomcat7 默认将用get传来的数据用ISO-8859-1封装, //将ajax传过来的值解码,再转码,//因为tomcat7 默认将用get ...

  5. python切片技巧

    写一个程序,打印数字1到100,3的倍数打印“Fizz”来替换这个数,5的倍数打印“Buzz”,对于既是3的倍数又是5的倍数的数字打印“FizzBuzz” for x in range(101): p ...

  6. 82. Single Number [easy]

    Description Given 2*n + 1 numbers, every numbers occurs twice except one, find it. Example Given [1, ...

  7. JavaScriptSerializer的实现-常用JsonHelper类

    最近开始自己写自己的项目了,终于鼓起勇气迈出了自己认为的这一大步! 先来通用的helper类和大家分享一下 ,第一个是Object转为json序列的类,这个网上有很多,但我实践了一下大部分都不能用的, ...

  8. usdt信息小结

    https://blog.csdn.net/weixin_42208011/article/details/80499536 https://blog.csdn.net/weixin_42208011 ...

  9. Mybatis generator自动生成mybatis配置和类信息

    自动生成代码方式两种: 1.命令形式生成代码,详细讲解每一个配置参数. 2.Eclipse利用插件形式生成代码. 安装插件方式: eclipse插件安装地址:http://mybatis.google ...

  10. Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题

    . 参考界面 : 携程app首页的广告栏, 使用ViewPager实现        自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...