先是维修数列

题解看这里,但是我写的跑得很慢

  1. #include <iostream>
  2. #include <cstdio>
  3. using namespace std;
  4. int n, m, idx[500005], a[500005], rot=0, uu, vv, sta[500005], din, ww, cnt;
  5. const int oo=0x3f3f3f3f;
  6. char ss[25];
  7. struct Splay{
  8. int zdz[500005], sum[500005], lma[500005], rma[500005], siz[500005], val[500005];
  9. int s[500005][2], fa[500005];
  10. bool tag[500005], rev[500005];
  11. void clr(int x){
  12. zdz[x] = sum[x] = lma[x] = rma[x] = siz[x] = val[x] = s[x][0] = s[x][1] = fa[x] = 0;
  13. tag[x] = rev[x] = 0;
  14. }
  15. int gx(int x){
  16. return s[fa[x]][1]==x;
  17. }
  18. void recycle(int x){
  19. if(s[x][0]) recycle(s[x][0]);
  20. if(s[x][1]) recycle(s[x][1]);
  21. sta[++din] = x;
  22. clr(x);
  23. }
  24. void upd(int x){
  25. int l=s[x][0], r=s[x][1];
  26. sum[x] = sum[l] + sum[r] + val[x];
  27. siz[x] = siz[l] + siz[r] + 1;
  28. zdz[x] = max(max(zdz[l], zdz[r]), lma[r]+val[x]+rma[l]);
  29. lma[x] = max(lma[l], sum[l]+val[x]+lma[r]);
  30. rma[x] = max(rma[r], sum[r]+val[x]+rma[l]);
  31. }
  32. void build(int l, int r, int f){
  33. int mid=(l+r)>>1, now=idx[mid], pre=idx[f];
  34. if(l==r){
  35. clr(now);
  36. zdz[now] = sum[now] = a[l];
  37. lma[now] = rma[now] = max(a[l], 0);
  38. siz[now] = 1;
  39. }
  40. if(l<mid) build(l, mid-1, mid);
  41. if(mid<r) build(mid+1, r, mid);
  42. val[now] = a[mid]; fa[now] = pre;
  43. upd(now);
  44. s[pre][mid>=f] = now;
  45. }
  46. void pushDown(int x){
  47. int l=s[x][0], r=s[x][1];
  48. if(tag[x]){
  49. tag[x] = rev[x] = 0;
  50. if(l) tag[l] = 1, val[l] = val[x], sum[l] = siz[l] * val[x];
  51. if(r) tag[r] = 1, val[r] = val[x], sum[r] = siz[r] * val[x];
  52. if(val[x]>=0){
  53. if(l) lma[l] = rma[l] = zdz[l] = sum[l];
  54. if(r) lma[r] = rma[r] = zdz[r] = sum[r];
  55. }
  56. else{
  57. if(l) lma[l] = rma[l] = 0, zdz[l] = val[x];
  58. if(r) lma[r] = rma[r] = 0, zdz[r] = val[x];
  59. }
  60. }
  61. if(rev[x]){
  62. rev[x] = false; rev[l] ^= 1; rev[r] ^= 1;
  63. swap(lma[l], rma[l]); swap(lma[r], rma[r]);
  64. swap(s[l][0], s[l][1]); swap(s[r][0], s[r][1]);
  65. }
  66. }
  67. int queryLoc(int x, int w){
  68. pushDown(x);
  69. if(w<=siz[s[x][0]]) return queryLoc(s[x][0], w);
  70. else if(w>siz[s[x][0]]+1) return queryLoc(s[x][1], w-siz[s[x][0]]-1);
  71. else return x;
  72. }
  73. void xf(int x){
  74. if(fa[x]) xf(fa[x]);
  75. pushDown(x);
  76. }
  77. void rotate(int x){
  78. int old=fa[x], oldf=fa[old], w=gx(x);
  79. s[old][w] = s[x][w^1]; s[x][w^1] = old;
  80. fa[s[old][w]] = old; fa[old] = x; fa[x] = oldf;
  81. if(oldf) s[oldf][s[oldf][1]==old] = x;
  82. else rot = x;
  83. upd(old); upd(x);
  84. }
  85. void splay(int x, int goal){
  86. xf(x);
  87. while(fa[x]!=goal){
  88. int f=fa[x];
  89. if(fa[f]!=goal) rotate(gx(f)==gx(x)?f:x);
  90. rotate(x);
  91. }
  92. upd(x);
  93. }
  94. void insert(int uu, int vv){
  95. for(int i=1; i<=vv; i++){
  96. scanf("%d", &a[i]);
  97. if(din) idx[i] = sta[din--];
  98. else idx[i] = ++cnt;
  99. }
  100. build(1, vv, 0);
  101. int ww=idx[(vv+1)>>1];
  102. int tx=queryLoc(rot, uu+1), ty=queryLoc(rot, uu+2);
  103. splay(tx, 0); splay(ty, rot);
  104. s[ty][0] = ww; fa[ww] = ty;
  105. upd(ty); upd(tx);
  106. }
  107. int spilt(int uu, int vv){
  108. int tx=queryLoc(rot, uu), ty=queryLoc(rot, uu+vv+1);
  109. splay(tx, 0); splay(ty, rot);
  110. return s[ty][0];
  111. }
  112. void shanssu(int uu, int vv){
  113. int x=spilt(uu, vv), y=fa[x];
  114. recycle(x); s[y][0] = 0;
  115. upd(y); upd(fa[y]);
  116. }
  117. void modify(int uu, int vv, int ww){
  118. int x=spilt(uu, vv), f=fa[x];
  119. val[x] = ww; tag[x] = true; sum[x] = siz[x] * ww;
  120. if(ww>=0) lma[x] = rma[x] = zdz[x] = sum[x];
  121. else lma[x] = rma[x] = 0, zdz[x] = ww;
  122. upd(f); upd(fa[f]);
  123. }
  124. void reverse(int uu, int vv){
  125. int x=spilt(uu, vv), f=fa[x];
  126. if(!tag[x]){
  127. rev[x] ^= 1;
  128. swap(s[x][0], s[x][1]);
  129. swap(lma[x], rma[x]);
  130. upd(f); upd(fa[f]);
  131. }
  132. }
  133. int getSum(int uu, int vv){
  134. int x=spilt(uu, vv);
  135. return sum[x];
  136. }
  137. }splay;
  138. int main(){
  139. cin>>n>>m;
  140. splay.zdz[0] = a[1] = a[n+2] = -oo;
  141. for(int i=1; i<=n; i++) scanf("%d", &a[i+1]);
  142. for(int i=1; i<=n+2; i++) idx[i] = i;
  143. splay.build(1, n+2, 0);
  144. rot = (n + 3) >> 1;
  145. cnt = n + 2;
  146. while(m--){
  147. scanf("%s", ss);
  148. if(ss[0]=='I'){
  149. scanf("%d %d", &uu, &vv);
  150. splay.insert(uu, vv);
  151. }
  152. if(ss[0]=='D'){
  153. scanf("%d %d", &uu, &vv);
  154. splay.shanssu(uu, vv);
  155. }
  156. if(ss[0]=='M' && ss[2]=='K'){
  157. scanf("%d %d %d", &uu, &vv, &ww);
  158. splay.modify(uu, vv, ww);
  159. }
  160. if(ss[0]=='R'){
  161. scanf("%d %d", &uu, &vv);
  162. splay.reverse(uu, vv);
  163. }
  164. if(ss[0]=='G'){
  165. scanf("%d %d", &uu, &vv);
  166. printf("%d\n", splay.getSum(uu, vv));
  167. }
  168. if(ss[0]=='M' && ss[2]=='X')
  169. printf("%d\n", splay.zdz[rot]);
  170. }
  171. return 0;
  172. }

下面是poj的,稍加改动即可ac洛谷。

如果想看题意分析及讲解请看这里,讲得很好,一下就让我明白splay维护区间了。

splay的价值在于维护区间,如果只是维护点的话完全可以用treap等平衡树代替

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. using namespace std;
  5. int n, m, uu, vv, ww, rot, sze;
  6. const int oo=0x3f3f3f3f;
  7. char ss[15];
  8. struct Splay{
  9. int s[200005][2], zxz[200005], val[200005], fa[200005], siz[200005];
  10. int rev[200005], tag[200005];
  11. void clr(int x){
  12. s[x][0] = s[x][1] = zxz[x] = val[x] = fa[x] = siz[x] = rev[x] = tag[x] = 0;
  13. }
  14. int gx(int x){
  15. return s[fa[x]][1]==x;
  16. }
  17. int newNode(int x){
  18. clr(++sze); siz[sze] = 1;
  19. val[sze] = zxz[sze] = x; return sze;
  20. }
  21. void ins(int x){
  22. newNode(x); s[rot][1] = sze; fa[sze] = rot; splay(sze, 0);
  23. }
  24. int queryLoc(int now, int x){
  25. pushDown(now);
  26. if(x<=siz[s[now][0]]) return queryLoc(s[now][0], x);
  27. else if(x>siz[s[now][0]]+1) return queryLoc(s[now][1], x-siz[s[now][0]]-1);
  28. else return now;
  29. }
  30. void upd(int x){
  31. siz[x] = siz[s[x][0]] + siz[s[x][1]] + 1;
  32. zxz[x] = val[x];
  33. if(s[x][0]) zxz[x] = min(zxz[x], zxz[s[x][0]]);
  34. if(s[x][1]) zxz[x] = min(zxz[x], zxz[s[x][1]]);
  35. }
  36. void rotate(int x){
  37. int old=fa[x], oldf=fa[old], w=gx(x);
  38. s[old][w] = s[x][w^1]; s[x][w^1] = old;
  39. fa[s[old][w]] = old; fa[old] = x; fa[x] = oldf;
  40. if(oldf) s[oldf][s[oldf][1]==old] = x;
  41. else rot = x;
  42. upd(old); upd(x);
  43. }
  44. void pushDown(int x){
  45. if(tag[x])
  46. for(int i=0; i<2; i++)
  47. if(s[x][i]){
  48. zxz[s[x][i]] += tag[x];
  49. val[s[x][i]] += tag[x];
  50. tag[s[x][i]] += tag[x];
  51. }
  52. if(rev[x]){
  53. if(s[x][0]) rev[s[x][0]] ^= 1;
  54. if(s[x][1]) rev[s[x][1]] ^= 1;
  55. swap(s[x][0], s[x][1]);
  56. }
  57. tag[x] = rev[x] = 0;
  58. }
  59. void xf(int x){
  60. if(fa[x]) xf(fa[x]);
  61. pushDown(x);
  62. }
  63. void splay(int x, int goal){
  64. xf(x);
  65. while(fa[x]!=goal){
  66. int f=fa[x];
  67. if(fa[f]!=goal) rotate(gx(x)==gx(f)?f:x);
  68. rotate(x);
  69. }
  70. upd(x);
  71. }
  72. void update(int uu, int vv, int ww){
  73. int tx=queryLoc(rot, uu), ty=queryLoc(rot, vv+2);
  74. splay(tx, 0); splay(ty, rot);
  75. val[s[ty][0]] += ww; zxz[s[ty][0]] += ww; tag[s[ty][0]] += ww;
  76. }
  77. void reverse(int uu, int vv){
  78. int tx=queryLoc(rot, uu), ty=queryLoc(rot, vv+2);
  79. splay(tx, 0); splay(ty, rot);
  80. rev[s[ty][0]] ^= 1;
  81. }
  82. void revolve(int uu, int vv, int ww){
  83. int len=vv-uu+1;
  84. ww = (ww%len+len)%len;
  85. int tx=queryLoc(rot, vv-ww+1), ty=queryLoc(rot, vv+2);
  86. int x=queryLoc(rot, uu), y=queryLoc(rot, uu+1);
  87. splay(tx, 0); splay(ty, rot);
  88. int tmp=s[ty][0]; s[ty][0] = 0;
  89. splay(x, 0); splay(y, rot);
  90. s[y][0] = tmp; fa[s[y][0]] = y;
  91. }
  92. void insert(int uu, int vv){
  93. int tx=queryLoc(rot, uu+1), ty=queryLoc(rot, uu+2);
  94. splay(tx, 0); splay(ty, rot);
  95. s[ty][0] = newNode(vv); fa[s[ty][0]] = ty;
  96. }
  97. void shanchu(int uu){
  98. int tx=queryLoc(rot, uu), ty=queryLoc(rot, uu+2);
  99. splay(tx, 0); splay(ty, rot);
  100. s[ty][0] = 0;
  101. }
  102. int queryMin(int uu, int vv){
  103. int tx=queryLoc(rot, uu), ty=queryLoc(rot, vv+2);
  104. splay(tx, 0); splay(ty, rot);
  105. return zxz[s[ty][0]];
  106. }
  107. }splay;
  108. int main(){
  109. cin>>n;
  110. rot = splay.newNode(oo);
  111. for(int i=1; i<=n; i++){
  112. scanf("%d", &uu);
  113. splay.ins(uu);
  114. }
  115. splay.ins(oo);
  116. cin>>m;
  117. while(m--){
  118. scanf("%s", ss);
  119. if(ss[0]=='A'){
  120. scanf("%d %d %d", &uu, &vv, &ww);
  121. splay.update(uu, vv, ww);
  122. }
  123. if(ss[0]=='R' && ss[3]=='E'){
  124. scanf("%d %d", &uu, &vv);
  125. splay.reverse(uu, vv);
  126. }
  127. if(ss[0]=='R' && ss[3]=='O'){
  128. scanf("%d %d %d", &uu, &vv, &ww);
  129. splay.revolve(uu, vv, ww);
  130. }
  131. if(ss[0]=='I'){
  132. scanf("%d %d", &uu, &vv);
  133. splay.insert(uu, vv);
  134. }
  135. if(ss[0]=='D'){
  136. scanf("%d", &uu);
  137. splay.shanchu(uu);
  138. }
  139. if(ss[0]=='M'){
  140. scanf("%d %d", &uu, &vv);
  141. printf("%d\n", splay.queryMin(uu, vv));
  142. }
  143. }
  144. return 0;
  145. }

splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)的更多相关文章

  1. luoguP3391[模板]文艺平衡树(Splay) 题解

    链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...

  2. 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay

    [阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...

  3. 【BZOJ-1500】维修数列 Splay

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 11047  Solved: 3460[Submit][Statu ...

  4. BZOJ 3223: Tyvj 1729 文艺平衡树-Splay树(区间翻转)模板题

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6881  Solved: 4213[Submit][Sta ...

  5. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  6. BZOJ3223 文艺平衡树(splay)

    题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...

  7. BZOJ3223: Tyvj 1729 文艺平衡树 [splay]

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3595  Solved: 2029[Submit][Sta ...

  8. Tyvj P1729 文艺平衡树 Splay

    题目: http://tyvj.cn/p/1729 P1729 文艺平衡树 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 此为平衡树系列第二道:文艺平衡树 ...

  9. BZOJ 3223: Tyvj 1729 文艺平衡树(splay)

    速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...

随机推荐

  1. css:hover伪类的使用

    :hover的使用,即当鼠标指针移入元素时,所做出的样式设置 示例一 <!DOCTYPE html> <html lang="en"> <head&g ...

  2. Hybrid框架安全隐患分析

    Hybrid框架安全隐患分析 目前我司移动端项目中各种app如雨后春笋般生根发芽层出不穷.而利用Hybrid框架确实可以减轻一部分移动端压力.并且做到灵活发版.但是其中的安全问题往往让人忽略. 针对A ...

  3. [SecureCRT]通过SFTP方式上传本地文件到服务器

    1.在本地建一个文件夹,如:d:\My Documents,在此目录下,放入我们需要上传的文件,如:nmon_linux_x86_64 2.然后打开我们的SecureCRT工具,一次选择Options ...

  4. 修改wamp的数据库密码

    方法/步骤     一:修改数据库密码 1.点开MySQL console进入数据库编辑框,然后按回车键,会出现图2的效果. 2.接着输入“use mysql” 下面提示“Database chang ...

  5. idea spring boot启动项目上面有红色叉

    一打开IDEA,在启动debug项目有一个红色叉如下图 因为打开项目可以主项目的包没有加载进来,解决办法就是右击项目->maven->Reimport  就搞定了..

  6. java基础—代理(proxy)

    一.代理的概念 动态代理技术是整个java技术中最重要的一个技术,它是学习java框架的基础,不会动态代理技术,那么在学习Spring这些框架时是学不明白的. 动态代理技术就是用来产生一个对象的代理对 ...

  7. 【转】VS2010下MFC的串口编程

    串口通信简介 一般来说,计算机都有一个或多个串行端口,这些串口提供了外部设备与PC进行数据传输和通信的通道,在CPU和外设之间充当解释器的角色.当字符数据从CPU发送给外设时,这些字符数据将被转换成串 ...

  8. 哈希表(Hash Table)/散列表(Key-Value)

    目录 1. 哈希表的基本思想 2. 哈希表的相关基本概念 1.概念: 2.哈希表和哈希函数的标准定义: 1)冲突: 2)安全避免冲突的条件: 3)冲突不可能完全避免 4)影响冲突的因素 3. 哈希表的 ...

  9. NOIP模拟赛 czy的后宫6

    czy的后宫6 题目描述 众所周知的是丧尸czy有很多妹子(虽然很多但是质量不容乐观QAQ),今天czy把n个妹子排成一行来检阅.但是czy的妹子的质量实在……所以czy看不下去了.检阅了第i个妹子会 ...

  10. 【MySql】Mysql ERROR 1067: Invalid default value for ‘date’ 解决

    在给一个表添加字段的时候,忽然发现会报一个date类型的字段的默认值错误,郁闷~ 经过排查,原来是MySQL的配置问题,在wamp下,MySQL 5.7里是没有设置 SQL_MODE 的. 1.my. ...