题面

题解

对于操作$1$,我们可以对于每个节点打一个$add$标记,下放就行了

对于操作2,可以参考这篇题解的上一篇,不赘述

对于操作4,可以将区间裂成两部分,然后再插入合并

对于操作5,可以将区间裂成三部分,删除其中一个部分,合并其他两部分

对于操作6,打一个$min$标记,具体可以看代码。


对于操作3,这个有点复杂,但是手玩可以发现,修改完后只是某两个断开的区间换了位置,只是断点不确定,算一下即可(细节有点多。)


#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm> template<typename T>
void read(T &x) {
int flag = 1; x = 0; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
} const int N = 2e5 + 10;
int n, m, lc[N], rc[N], siz[N], val[N], pri[N], rev[N], add[N], mn[N], tot; inline void rotate(int o) { std::swap(lc[o], rc[o]), rev[o] ^= 1; }
inline void __add(int o, int v) { val[o] += v, mn[o] += v, add[o] += v; }
inline void upt(int o) {
siz[o] = siz[lc[o]] + siz[rc[o]] + 1, mn[o] = val[o];
if(lc[o]) mn[o] = std::min(mn[o], mn[lc[o]]);
if(rc[o]) mn[o] = std::min(mn[o], mn[rc[o]]);
}
inline int node(int x) {
val[++tot] = x, pri[tot] = rand(), siz[tot] = 1, mn[tot] = x;
return tot;
}
void pushdown(int o) {
if(add[o]) {
if(lc[o]) __add(lc[o], add[o]);
if(rc[o]) __add(rc[o], add[o]);
add[o] = 0;
}
if(rev[o]) {
if(lc[o]) rotate(lc[o]);
if(rc[o]) rotate(rc[o]);
rev[o] = 0;
}
}
void split(int o, int k, int &l, int &r) {
if(!o) { l = r = 0; return ; } pushdown(o);
if(siz[lc[o]] < k) l = o, split(rc[o], k - siz[lc[o]] - 1, rc[o], r);
else r = o, split(lc[o], k, l, lc[o]);
upt(o);
}
int merge(int l, int r) {
if(!l || !r) return l + r;
pushdown(l), pushdown(r);
if(pri[l] < pri[r]) { rc[l] = merge(rc[l], r), upt(l); return l; }
else { lc[r] = merge(l, lc[r]), upt(r); return r; }
} int main () {
read(n), srand(19260817);
int x, y, l, r, k, rt = 0, D, T;
for(int i = 1; i <= n; ++i)
read(x), rt = merge(rt, node(x));
read(m); char opt[10];
for(int i = 1; i <= m; ++i) {
scanf("%s", opt), read(x);
if(opt[0] == 'A') {
read(y), read(D);
split(rt, y, l, r), split(l, x - 1, l, k);
__add(k, D), rt = merge(merge(l, k), r);
}
if(opt[0] == 'R' && opt[3] == 'E') {
read(y), split(rt, y, l, r), split(l, x - 1, l, k);
rotate(k), rt = merge(merge(l, k), r);
}
if(opt[0] == 'R' && opt[3] == 'O') {
read(y), read(T);
T %= (y - x + 1);
if(!T) continue;
T = (y - x + 1) - T;
split(rt, y, l, r), split(l, x - 1, l, k);
split(k, T, k, D);
rt = merge(merge(l, merge(D, k)), r);
}
if(opt[0] == 'I') read(y), split(rt, x, l, r), rt = merge(merge(l, node(y)), r);
if(opt[0] == 'D') split(rt, x, l, r), split(l, x - 1, l, k), rt = merge(l, r);
if(opt[0] == 'M') {
read(y), split(rt, y, l, r), split(l, x - 1, l, k);
printf("%d\n",mn[k]), rt = merge(merge(l, k), r);
}
}
return 0;
}

最新文章

  1. [示例] Firemonkey 不规则按钮实做
  2. Android通过PHP服务器实现登录
  3. Android Http请求框架二:xUtils 框架网络请求
  4. linux下批量修改存有超大数据量IP文件中的IP内容以及去重排序
  5. LeetCode Expression Add Operators
  6. Rs2008内存管理策略
  7. 多线程/进度条应用(progressbar)
  8. IOS Label 自动换行 IOS6和IOS7
  9. 既然HTTP1.1协议里每个连接默认都是持久连接,那么为何当今所有报文都在使用Connetion:Keep-Alive
  10. Ubuntu Mysql开通外网访问权限
  11. 用Ajax实现自动刷新news功能
  12. Head First 设计模式 第2章 观察者模式
  13. 网络基础tcp/ip协议三
  14. Struts2实现文件上传(四)
  15. 笔记:Hibernate 查询缓存
  16. Tomcat9使用免费的Https证书加密网站
  17. 经典JS的HTML转义与反转义字符
  18. 关于SQL2008R2连接服务器出错问题
  19. 2.04-proxy-handler
  20. A1133. Splitting A Linked List

热门文章

  1. SPOJ 104 HIGH - Highways
  2. mysql创建用户,并授权
  3. WCF使用注意事项
  4. 【hdu1255】线段树求矩形面积交
  5. 20155335俞昆《java程序设计》第十周总结
  6. cocos2dx 某缩放的页面 CCTableView最后一个标签无法点中
  7. Can you answer these queries?(HDU4027+势能线段树)
  8. Farey Sequence (欧拉函数+前缀和)
  9. Ribbon的主要组件与工作流程
  10. Python3 PyPAML 模块(配置文件的操作)