Problem 平衡树 splay2

题目大意

  维护一个序列,支持四种操作:

  操作1:添加一个数,编号为x,权值为y。

  操作2:删除编号在区间【x,y】内的数。

  操作3:将编号在区间【x,y】内的数的权值增加为z。

  操作4:询问编号在区间【x,y]内的数的权值和。

解题分析

  由于增加了区间加和区间查询,所以要给每个增加一个lazy标记。

  在每次搜索树的时候要对每个经过的节点进行一次pushdown,当树的形态或树的结点信息改变时要进行一次pushup。

参考程序

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. int tag=;
  5.  
  6. struct node{
  7. int id,num;
  8. long long lazy,val,sum;
  9. node *left,*right,*father;
  10. node(int id_=,long long val_=,int num_=,long long lazy_=,long long sum_=,node* father_=NULL,node* left_=NULL,node* right_=NULL)
  11. {
  12. id=id_; val=val_; num=num_; lazy=lazy_; sum=sum_;
  13. father=father_; left=left_; right=right_;
  14. }
  15. }*rt,*t1,*t2;
  16.  
  17. void search(node *now)
  18. {
  19. cout<<now->id; cout<<" val= "<<now->val<<" sum= "<<now->sum<<" num= "<<now->num<<" lazy= "<<now->lazy;
  20. if (now->left) cout<<" lson: "<<now->left->id;
  21. if (now->right) cout<<" rson: "<<now->right->id;
  22. cout<<endl;
  23. if (now->left) search(now->left);
  24. if (now->right) search(now->right);
  25. }
  26.  
  27. void pushup(node* x)
  28. {
  29. x->sum=x->val; x->num=;
  30. if (x->left) x->sum+=x->left->sum,x->num+=x->left->num;
  31. if (x->right) x->sum+=x->right->sum,x->num+=x->right->num;
  32. }
  33.  
  34. void pushdown(node* x)
  35. {
  36. if (x->lazy)
  37. {
  38. node *l = x->left,*r = x->right;
  39. if (l)
  40. {
  41. l->lazy += x->lazy;
  42. l->val += x->lazy;
  43. l->sum += x->lazy * l->num;
  44. }
  45. if (r)
  46. {
  47. r->lazy += x->lazy;
  48. r->val += x->lazy;
  49. r->sum += x->lazy * r->num;
  50. }
  51. x->lazy = ;
  52. }
  53. }
  54.  
  55. void right(node* x,node* &rt)
  56. {
  57. node *y=x->father,*z=y->father;
  58. if (y==rt) rt=x;
  59. else if (z->left==y) z->left=x; else z->right=x; //需要判断是左右孩子
  60. x->father=z; y->father=x; if (x->right) x->right->father=y; //防止对空指针进行操作
  61. y->left=x->right; x->right=y;
  62. pushup(y); pushup(x);
  63. }
  64.  
  65. void left(node* x,node* &rt)
  66. {
  67. node *y=x->father,*z=y->father;
  68. if (y==rt) rt=x;
  69. else if (z->left==y) z->left=x; else z->right=x;
  70. x->father=z; y->father=x; if (x->left) x->left->father=y;
  71. y->right=x->left; x->left=y;
  72. pushup(y); pushup(x);
  73. }
  74.  
  75. void splay(node* x,node* &rt)
  76. {
  77. while (x!=rt)
  78. {
  79. node *y=x->father, *z=y->father;
  80. if (y==rt)
  81. {
  82. if (x==y->left) right(x,rt);
  83. else left(x,rt);
  84. }
  85. else
  86. {
  87. if (y==z->left)
  88. if (x==y->left) { right(y,rt); right(x,rt); }
  89. else { left(x,rt); right(x,rt); }
  90. else
  91. if (x==y->right) { left(y,rt); left(x,rt); }
  92. else { right(x,rt); left(x,rt); }
  93. }
  94. }
  95. }
  96.  
  97. void insert(int id,int val,node* &now,node *last)
  98. {
  99. if (now==NULL)
  100. {
  101. now=new node(id,val,,,val,last);
  102. splay(now,rt);
  103. return;
  104. }
  105. pushdown(now);
  106. if (id < now->id) insert(id,val,now->left,now); else insert(id,val,now->right,now);
  107. //else还是要加的 返回的时候树的形态已经改变了
  108. }
  109.  
  110. void find_1(int id,node *x)
  111. {
  112. if (x==NULL) return;
  113. pushdown(x);
  114. if (x->id>=id) find_1(id,x->left);
  115. else {t1=x; find_1(id,x->right);}
  116. }
  117.  
  118. void find_2(int id,node *x)
  119. {
  120. if (x==NULL) return;
  121. pushdown(x);
  122. if (x->id<=id) find_2(id,x->right);
  123. else {t2=x; find_2(id,x->left);}
  124. }
  125.  
  126. void del(int l,int r)
  127. {
  128. t1=t2=NULL;
  129. find_1(l,rt); splay(t1,rt);
  130. find_2(r,rt->right); splay(t2,rt->right);
  131. rt->right->left=NULL;
  132. pushup(rt->right); pushup(rt);
  133. }
  134.  
  135. void add(int l,int r,int val)
  136. {
  137. t1=t2=NULL;
  138. find_1(l,rt); splay(t1,rt);
  139. find_2(r,rt->right); splay(t2,rt->right);
  140. if (rt->right->left)
  141. {
  142. rt->right->left->lazy += val;
  143. rt->right->left->sum += 1ll* val * rt->right->left->num;
  144. rt->right->left->val += val;
  145. }
  146. pushup(rt->right); pushup(rt);
  147. }
  148.  
  149. long long query(int l,int r)
  150. {
  151. t1=t2=NULL;
  152. find_1(l,rt); splay(t1,rt);
  153. find_2(r,rt->right); splay(t2,rt->right);
  154. if (rt->right->left)
  155. return rt->right->left->sum;
  156. else return ;
  157. }
  158.  
  159. int main()
  160. {
  161. int n;
  162. rt=NULL;
  163. scanf("%d",&n);
  164. insert(<<,,rt,NULL); insert(-<<,,rt,NULL);
  165. for (int i=;i<=n;i++)
  166. {
  167. char s[]; int x,y,z;
  168. scanf("%s%d%d",s,&x,&y);
  169. if (s[]=='I') insert(x,y,rt,NULL);
  170. if (s[]=='D') del(x,y);
  171. if (s[]=='M')
  172. {
  173. scanf("%d",&z);
  174. add(x,y,z);
  175. }
  176. if (s[]=='Q') cout<<query(x,y)<<endl;
  177. }
  178. }

Hihocoder 1333 (splay)的更多相关文章

  1. Hihocoder 1325 (splay)

    Problem 平衡树 Treap 题目大意 维护一个数列,支持两种操作. 操作1:添加一个数x. 操作2:询问不超过x的最大的数. 解题分析 尝试了一下用指针来写splay,感觉写起来还是比较流畅的 ...

  2. Hihocoder 1329(splay)

    Problem 平衡树 Splay 题目大意 维护一个数列,支持三种操作. 操作1:添加一个数x. 操作2:询问不超过x的最大的数. 操作三:删除大小在区间[a,b]内的数. 解题分析 和上一题相比, ...

  3. 【BZOJ3506】排序机械臂(Splay)

    [BZOJ3506]排序机械臂(Splay) 题面 神TMBZOJ没有题面,感谢SYC的题面 洛谷的题面也不错 题解 对于每次旋转的物体 显然可以预处理出来 现在只要模拟旋转操作就行了 至于在哪里放标 ...

  4. 【BZOJ1500】【NOI2005】维修数列(Splay)

    [BZOJ1500][NOI2005]维修数列(Splay) 题面 不想再看见这种毒瘤题,自己去BZOJ看 题解 Splay良心模板题 真的很简单 我一言不发 #include<iostream ...

  5. 【BZOJ1862】[ZJOI2006]游戏排名系统 (Splay)

    [BZOJ1862][ZJOI2006]游戏排名系统 (Splay) 题面 BZOJ 洛谷 题解 双倍经验题

  6. 【BZOJ1056】[HAOI2008]排名系统(Splay)

    [BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...

  7. 【BZOJ2329】括号修复(Splay)

    [BZOJ2329]括号修复(Splay) 题面 BZOJ 洛谷 题解 本来想着用线段树来写 但是有一个区间翻转 所以不能用线段树了,就只能用平衡树 然后直接\(Splay\)就好了 注意一下几个标记 ...

  8. P3391 【模板】文艺平衡树(Splay)新板子

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

  9. fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)

    题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...

随机推荐

  1. Nginx(一) 安装基于centos7

    1.   nginx介绍 1.1. 什么是nginx Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.由俄罗斯的程序设计师Igor Sysoev所开 ...

  2. Winform执行CMD命令

    1.首先分享CmdHelper类: using System; using System.Collections.Generic; using System.Text; using System.Di ...

  3. 洛谷 P1582 倒水

    题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒 ...

  4. 258 Add Digits 各位相加

    给一个非负整数 num,反复添加所有的数字,直到结果只有一个数字.例如:设定 num = 38,过程就像: 3 + 8 = 11, 1 + 1 = 2. 由于 2 只有1个数字,所以返回它.进阶:你可 ...

  5. SpringMVC高级课程

    requestBody和responseBody requestBody把前台页面传递JSON格式数据强制转换JavaBean responseBody在后台把javabean转换成JSON格式的数据 ...

  6. 转载pcb设计详细版

    http://www.51hei.com/bbs/dpj-52438-1.html 详细的altium designer制作PCB步骤,按照步骤一步步的学习就会自己制作PCB模型 目 录 实验三  层 ...

  7. Slow HTTP Denial of Service Attack 漏洞解决办法

    编辑 删除 问题名称: Slow HTTP Denial of Service Attack 问题URL http://10.238.*.*:58*** 风险等级: 高 问题类型: 服务器配置类 漏洞 ...

  8. [Windows Server 2008] Windows防火墙设置

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:如何开启W ...

  9. Ajax异步刷新省市级联

    省市级联在web前端用户注册使用非常广泛.Ajax异步刷新省市级联.如图:选择不同的区,自动加载相应的街. <TD class=field>位 置:</TD> <TD&g ...

  10. LockDemo 锁对象

    class Resource { private boolean flag = false; private String name; private int count; //资源锁 Lock lo ...