CF 558E A Simple Task (线段树)
来源:互联网 发布:这样更换ubuntu的主题 编辑:程序博客网 时间:2024/06/11 11:44
Description
给定一个长度为
Solution
法一
由于只有26种元素,考虑用线段树维护每个节点所包含的每个字母的个数以及该区间内是降序还是升序或者乱序,直接维护即可
法二
考虑用set维护,一开始每一个字母都是一个独立的集合,每次操作将两端的集合暴力拆开,将中间的字母集合合并
时间复杂度
Code
法一
#10916296 | HanYi's solution for [CodeForces-558E]Status AcceptedTime 312msMemory 43948kBLength 4298Lang GNU G++11 5.1.0Submitted 2017-10-03 15:45:23Shared RemoteRunId 30961190Select Code//LuanGao#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<iostream>#include<algorithm>#include<queue>#include<vector>#include<set>#define For(i , j , k) for (int i = (j) , _##end_ = (k) ; i <= _##end_ ; ++ i)#define Fordown(i , j , k) for (int i = (j) , _##end_ = (k) ; i >= _##end_ ; -- i)#define Set(a , b) memset(a , b , sizeof(a))#define pb push_back#define lc (t << 1)#define rc (t << 1 | 1)#define mid ((l + r) >> 1)#define INF (0x3f3f3f3f)#define Mod (1000000007)using namespace std;typedef long long LL;template <typename T> inline bool chkmax(T &a , T b) { return a < b ? (a = b , 1) : 0; }template <typename T> inline bool chkmin(T &a , T b) { return b < a ? (a = b , 1) : 0; }int _ , __;char c_;inline int read(){ for (_ = 0 , __ = 1 , c_ = getchar() ; !isdigit(c_) ; c_ = getchar()) if (c_ == '-') __ = -1; for ( ; isdigit(c_) ; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48); return _ * __;}inline void file(){#ifndef ONLINE_JUDGE freopen("string.in" , "r" , stdin); freopen("string.out" , "w" , stdout);#endif}const int maxn = 100010;struct Item{ int a[27] , type; //type = 0: LuanXu //type = 1: ShengXu //type = 2: JiangXu}tr[maxn * 4] , d , tmp;Item operator + (const Item &A , const Item &B){ Item C; C.type = 0; For(i , 0 , 25) C.a[i] = A.a[i] + B.a[i]; return C;}inline void clear(int t){ For(i , 0 , 25) tr[t].a[i] = 0;}int n , m , x , y , type;char s[maxn];inline void maintain(int t) { tr[t] = tr[lc] + tr[rc]; }inline void pushdown(int t , int l , int r){ tmp = tr[t]; if (tmp.type == 1 || tmp.type == 2) tr[lc].type = tr[rc].type = tmp.type; int res = mid - l + 1; if (tr[t].type == 1) { clear(lc); For(i , 0 , 25) { if (tmp.a[i] <= res) { tr[lc].a[i] = tmp.a[i]; res -= tmp.a[i]; tmp.a[i] = 0; } else { tmp.a[i] -= res; tr[lc].a[i] = res; res = 0; } } tr[rc] = tmp; } else if (tr[t].type == 2) { clear(lc); Fordown(i , 25 , 0) { if (tmp.a[i] <= res) { tr[lc].a[i] = tmp.a[i]; res -= tmp.a[i]; tmp.a[i] = 0; } else { tmp.a[i] -= res; tr[lc].a[i] = res; res = 0; break; } } tr[rc] = tmp; }}void build(int t , int l , int r){ if (l == r) { tr[t].a[s[l] - 97] = 1; return ; } build(lc , l , mid); build(rc , mid + 1 , r); maintain(t);}Item query(int t , int l , int r){ if (x <= l && r <= y) return tr[t]; pushdown(t , l , r); if (x > mid) return query(rc , mid + 1 , r); if (y <= mid) return query(lc , l , mid); return query(rc , mid + 1 , r) + query(lc , l , mid);}void update1(int t , int l , int r){ if (x <= l && r <= y) { tr[t].type = 1; int res = r - l + 1; clear(t); For(i , 0 , 25) { if (d.a[i] <= res) { tr[t].a[i] = d.a[i]; res -= d.a[i]; d.a[i] = 0; } else { d.a[i] -= res; tr[t].a[i] = res; res = 0; break; } } return ; } pushdown(t , l , r); if (x <= mid) update1(lc , l , mid); if (y > mid) update1(rc , mid + 1 , r); tr[t].type = 0; maintain(t);}void update2(int t , int l , int r){ if (x <= l && r <= y) { tr[t].type = 2; int res = r - l + 1; clear(t); Fordown(i , 25 , 0) { if (d.a[i] <= res) { tr[t].a[i] = d.a[i]; res -= d.a[i]; d.a[i] = 0; } else { d.a[i] -= res; tr[t].a[i] = res; res = 0; break; } } return ; } pushdown(t , l , r); if (x <= mid) update2(lc , l , mid); if (y > mid) update2(rc , mid + 1 , r); tr[t].type = 0; maintain(t);}void print(int t , int l , int r){ if (l == r) For(i , 0 , 25) if (tr[t].a[i]) { putchar(i + 97); return; } if (tr[t].type == 1) { For(i , 0 , 25) For(j , 1 , tr[t].a[i]) putchar(i + 97); return ; } if (tr[t].type == 2) { Fordown(i , 25 , 0) For(j , 1 , tr[t].a[i]) putchar(i + 97); return ; } pushdown(t , l , r); print(lc , l , mid); print(rc , mid + 1 , r);}int main(){ file(); n = read(); m = read(); scanf("%s" , s + 1); build(1 , 1 , n); while (m --) { x = read(); y = read(); type = read(); d = query(1 , 1 , n); if (type) update1(1 , 1 , n); else update2(1 , 1 , n); } print(1 , 1 , n); putchar('\n'); return 0;}
阅读全文
0 0
- CF 558E A Simple Task(多维线段树)
- CF 558E A Simple Task (线段树)
- CF 558E(A Simple Task-计数排序+线段树)
- cf #312 E. A Simple Task (线段树+计数排序)
- cf#312-E-A Simple Task- 线段树+暴力(计数排序)
- codeforces 558E A Simple Task 线段树
- Codeforces 558E. A Simple Task (线段树+计数排序)
- [线段树] codeforces 558E. A Simple Task
- Codeforces 558E A Simple Task(线段树区间更新)
- Codeforces 558E A Simple Task 线段树(区间更新)
- codeforces 558E E. A Simple Task( 线段树+统计排序)
- [计数排序 线段树] Codeforces 558E #312 (Div. 2) E. A Simple Task
- Codeforces 558E A Simple Task (计数排序+线段树优化)
- 计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树(未敲)
- codeforces 558 E A Simple Task
- 【30.93%】【codeforces 558E】A Simple Task
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树 延时标记
- 前端常用的UI插件
- python 线程setDaemon(True)
- js中Function.prototype的bind()方法-学习笔记
- ICMP协议
- $(function(){ }与window.onload = function(){ }的区别
- CF 558E A Simple Task (线段树)
- 蓝桥杯 算法提高 大数加法
- TCP粘包问题
- Linux常用命令
- 10.6考察自增自减、修饰符、类变量的调用、成员变量的调用、运算符的优先级、鲁棒性、异常总结
- 神经网络算法(Nerual Networks)应用
- 剑指offer之十六---栈的压入、弹出序列
- 树莓派上的软件安装和卸载命令汇总
- java web分页bean