hihocoder#1333 : 平衡树·Splay2 (区间操作)
题面:
#1333 : 平衡树·Splay2
描述
小Ho:好麻烦啊~~~~~
小Hi:小Ho你在干嘛呢?
小Ho:我在干活啊!前几天老师让我帮忙管理一下团队的人员,但是感觉好难啊。
小Hi:说来听听?
小Ho:事情是这样的。我们有一个运动同好会,每天都有人加入或者退出,所以老师让我帮忙管理一下人员。每个成员有一个互不相同的id和他对我们同好会的兴趣值val,每隔一段时间一些成员的兴趣值就会发生变化。老师有时候也会问我一些成员的兴趣值。
小Hi:所以你就需要一个表格来管理信息咯?
小Ho:是啊,但是我们同好会的成员实在是太多了!我感觉完全搞不定啊。
小Hi:这样啊,那不如让我来帮帮你吧!
小Ho:真的吗?
小Hi:当然是真的啦,小Ho,你先告诉我有多少种需要完成的事情?
小Ho:一共有4种情况:
1. 加入:一个新的成员加入同好会,我会分配给他一个没有使用的id,并且询问他的兴趣值val。
2. 修改:id在区间[a,b]内的成员,兴趣值同时改变k,k有可能是负数,表示他们失去了对同好会的兴趣。
3. 退出:id在区间[a,b]内的成员要退出同好会,虽说是区间,也有可能只有1个人。
4. 询问:老师会问我在区间[a,b]内的成员总的兴趣值。
小Hi:我明白了,让我想一想该如何解决。
输入
第1行:1个正整数n,表示操作数量,100≤n≤200,000
第2..n+1行:可能包含下面4种规则:
1个字母'I',紧接着2个数字id,val,表示一个编号为id的新成员加入,其兴趣值为val,1≤id≤100,000,000,1≤val≤10,000,000,保证在团队中的每个人id都不相同。
1个字母'Q',紧接着2个数字a,b。表示询问团队中id在区间[a,b]的所有成员总兴趣值,保证区间内至少有一个成员,结果有可能超过int的范围。
1个字母'M',紧接着3个数字a,b,d,表示将团队中id在区间[a,b]的成员兴趣值都改变d,其中d有可能为负数。保证操作之后每个成员的兴趣值仍然在0~10,000,000。
1个字母'D',紧接着2个数字a,b,表示将团队中id在区间[a,b]的成员除去。
注意有可能出现一个id为1的成员加入团队,被除去之后,又有一个新的id为1的成员加入团队的情况。
输出
若干行:每行1个整数,表示针对询问的回答,保证一定有合法的解
- 样例输入
-
9
I 1 1
I 2 2
I 3 3
Q 1 3
M 1 2 2
Q 1 3
D 2 3
I 4 2
Q 1 4 - 样例输出
-
6
10
5 链接:http://hihocoder.com/problemset/problem/1333 代码:#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll M = 2e5+;
const ll inf = 0x3f3f3f;
ll n,sz,rt,t1,t2;
ll c[M][],sum[M],fa[M],id[M],tag[M],v[M],siz[M];
inline void pushup(ll k){
ll l = c[k][],r = c[k][];
sum[k] = sum[l] + sum[r] + v[k];
siz[k] = siz[l] + siz[r] + ;
} void pushdown(ll k){
ll l = c[k][],r = c[k][],t = tag[k];
if(t){
tag[k] = ;
if(l) tag[l]+=t,sum[l]+=t*siz[l],v[l]+=t;
if(r) tag[r]+=t,sum[r]+=t*siz[r],v[r]+=t;
}
} void rotate(ll x,ll &k){
ll y = fa[x],z = fa[y],l,r;
if(c[y][] == x) l = ;
else l = ;
r = l^;
if(y == k) k = x;
else {
if(c[z][]==y) c[z][]=x;
else c[z][] = x;
}
fa[x] = z;fa[y] = x;fa[c[x][r]]=y;
c[y][l]=c[x][r]; c[x][r]=y;
pushup(y); pushup(x);
} void splay(ll x,ll &k){
while(x != k){
ll y = fa[x],z = fa[y];
if(y != k){
if(c[y][]==x^c[z][]==y)rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
} inline void ask_befor(ll k,ll x){
pushdown(k);
if(k == ) return ;
if(id[k] <= x) {
t1 = k;
ask_befor(c[k][],x);
}
else ask_befor(c[k][],x);
} inline void ask_after(ll k,ll x){
pushdown(k);
if(k == ) return ;
if(id[k] >= x) {
t2 = k;
ask_after(c[k][],x);
}
else ask_after(c[k][],x);
} inline void ins(ll &k,ll idx,ll val,ll last){
pushdown(k);
if(k == ){
++sz;
siz[sz] = ;
k = sz;
v[k] = val;
sum[k] = val;
fa[k] = last;
id[k] = idx;
return ;
}
if(idx < id[k]) ins(c[k][],idx,val,k);
else ins(c[k][],idx,val,k);
pushup(k);
} inline void update(ll l,ll r,ll val){
ask_befor(rt,l-);ask_after(rt,r+);
ll x = t1,y = t2;
splay(x,rt); splay(y,c[x][]);
ll z = c[y][];
tag[z] += val;v[z] += val; sum[z] += val*siz[z];
} void del(ll l,ll r){
ask_befor(rt,l-);ask_after(rt,r+);
ll x = t1,y = t2;
splay(x,rt); splay(y,c[x][]);
c[y][] = ;
} inline void query(ll l,ll r){
ask_befor(rt,l-);ask_after(rt,r+);
ll x = t1,y = t2;
splay(x,rt); splay(y,c[x][]);
ll z = c[y][];
printf("%lld\n",sum[z]);
} int main()
{
sz = ;
ins(rt,-,,);
ins(rt,,,rt);
scanf("%lld",&n);
for(ll i = ;i <= n;i ++){
ll l,r,val;
string s;
cin>>s;
//cout<<s[0]<<endl;
scanf("%lld%lld",&l,&r);
if(s[] == 'M') scanf("%lld",&val),update(l,r,val);
else if(s[] == 'I') ins(rt,l,r,rt),splay(sz,rt);
else if(s[] == 'Q') query(l,r);
else del(l,r);
}
return ;
}
hihocoder#1333 : 平衡树·Splay2 (区间操作)的更多相关文章
- Hihocoder #1333 : 平衡树·Splay2
1333 : 平衡树·Splay2 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:好麻烦啊~ 小Hi:小Ho你在干嘛呢? 小Ho:我在干活啊!前几天老师让我帮忙 ...
- hihocoder #1333 : 平衡树·Splay2
描述 小Ho:好麻烦啊~~~~~ 小Hi:小Ho你在干嘛呢? 小Ho:我在干活啊!前几天老师让我帮忙管理一下团队的人员,但是感觉好难啊. 小Hi:说来听听? 小Ho:事情是这样的.我们有一个运动同好会 ...
- Hihocoder 1329 平衡树·Splay(平衡树)
Hihocoder 1329 平衡树·Splay(平衡树) Description 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. 小Hi:怎么了? 小Ho:小H ...
- Hihocoder 1333 (splay)
Problem 平衡树 splay2 题目大意 维护一个序列,支持四种操作: 操作1:添加一个数,编号为x,权值为y. 操作2:删除编号在区间[x,y]内的数. 操作3:将编号在区间[x,y]内的数的 ...
- Hihocoder 1325 平衡树·Treap(平衡树,Treap)
Hihocoder 1325 平衡树·Treap(平衡树,Treap) Description 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二叉 ...
- HihoCoder 1325 平衡树·Treap
HihoCoder 1325 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说 ...
- Splay 的区间操作
学完Splay的查找作用,发现和普通的二叉查找树没什么区别,只是用了splay操作节省了时间开支. 而Splay序列之王的称号可不是白给的. Splay真正强大的地方是他的区间操作. 怎么实现呢? 我 ...
- POJ 3225 Help with Intervals --线段树区间操作
题意:给你一些区间操作,让你输出最后得出的区间. 解法:区间操作的经典题,借鉴了网上的倍增算法,每次将区间乘以2,然后根据区间开闭情况做微调,这样可以有效处理开闭区间问题. 线段树维护两个值: cov ...
- P2042 [NOI2005]维护数列 && Splay区间操作(四)
到这里 \(A\) 了这题, \(Splay\) 就能算入好门了吧. 今天是个特殊的日子, \(NOI\) 出成绩, 大佬 \(Cu\) 不敢相信这一切这么快, 一下子机房就只剩我和 \(zrs\) ...
随机推荐
- mariadb(第五章)视图、事物、索引、外键
视图 对于复杂的查询,在多个地方被使用,如果需求发生了改变,需要更改sql语句,则需要在多个地方进行修改,维护起来非常麻烦 假如因为某种需求,需要将user拆房表usera和表userb,该两张表的结 ...
- Docker镜像的修改和自定义
一.docker镜像的更新 (1)启动镜像,写入一些文件或者更新软件 docker run -it 3afd47092a0e[root@44652ba46352 /]# ls (2)更新镜像 dock ...
- Mysql启动找不到mysql.sock文件问题(Centos7)
刚装完Mysql5.7,将Mysql添加到开机自启.reboot之后mysql服务却没启动起来, 直接输入mysql –uroot –p ,出现如下错误,找不到mysql.sock文件.用servic ...
- H5 62-浮动元素字围现象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Python—函数的名称空间
名称空间 又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方 名称空间共3种, ...
- org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.bw.mapper.BillMapper.getBillList at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:225
这个错误是没有找到映射文件 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.b ...
- js-跨域源资源共享(CORS)
### 一. CORS(Cross-Origin Resource Sharing,跨域源资源共享) 基本思想:使用自定义HTTP头部让浏览器与服务器进行沟通 发送请求时,需附加一个Origin头部 ...
- css小demo
span{ color: #ccc; float: right; font-weight: bold; display: inline-block; border-right: solid 1px # ...
- 《Effective C++》资源管理:条款13-条款17
条款13:以对象管理资源 为了防止资源泄漏,请使用RAII(Resource Acquisition Is Initialization)对象,在构造函数里面获得资源,在析构函数里面释放资源 auto ...
- 372.Definition of ListNode
单项列表只能把后一个node中的所有数据copy到当前node再delete后一node. /** * Definition of ListNode * class ListNode { * publ ...