题面:

#1333 : 平衡树·Splay2

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小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:我明白了,让我想一想该如何解决。

提示:Splay

输入

第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 (区间操作)的更多相关文章

  1. Hihocoder #1333 : 平衡树·Splay2

    1333 : 平衡树·Splay2 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:好麻烦啊~ 小Hi:小Ho你在干嘛呢? 小Ho:我在干活啊!前几天老师让我帮忙 ...

  2. hihocoder #1333 : 平衡树·Splay2

    描述 小Ho:好麻烦啊~~~~~ 小Hi:小Ho你在干嘛呢? 小Ho:我在干活啊!前几天老师让我帮忙管理一下团队的人员,但是感觉好难啊. 小Hi:说来听听? 小Ho:事情是这样的.我们有一个运动同好会 ...

  3. Hihocoder 1329 平衡树·Splay(平衡树)

    Hihocoder 1329 平衡树·Splay(平衡树) Description 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. 小Hi:怎么了? 小Ho:小H ...

  4. Hihocoder 1333 (splay)

    Problem 平衡树 splay2 题目大意 维护一个序列,支持四种操作: 操作1:添加一个数,编号为x,权值为y. 操作2:删除编号在区间[x,y]内的数. 操作3:将编号在区间[x,y]内的数的 ...

  5. Hihocoder 1325 平衡树·Treap(平衡树,Treap)

    Hihocoder 1325 平衡树·Treap(平衡树,Treap) Description 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二叉 ...

  6. HihoCoder 1325 平衡树·Treap

    HihoCoder 1325 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说 ...

  7. Splay 的区间操作

    学完Splay的查找作用,发现和普通的二叉查找树没什么区别,只是用了splay操作节省了时间开支. 而Splay序列之王的称号可不是白给的. Splay真正强大的地方是他的区间操作. 怎么实现呢? 我 ...

  8. POJ 3225 Help with Intervals --线段树区间操作

    题意:给你一些区间操作,让你输出最后得出的区间. 解法:区间操作的经典题,借鉴了网上的倍增算法,每次将区间乘以2,然后根据区间开闭情况做微调,这样可以有效处理开闭区间问题. 线段树维护两个值: cov ...

  9. P2042 [NOI2005]维护数列 && Splay区间操作(四)

    到这里 \(A\) 了这题, \(Splay\) 就能算入好门了吧. 今天是个特殊的日子, \(NOI\) 出成绩, 大佬 \(Cu\) 不敢相信这一切这么快, 一下子机房就只剩我和 \(zrs\) ...

随机推荐

  1. eclipse 执行自带的maven命令无效

    原文地址:https://blog.csdn.net/qq_26386171/article/details/78262702 下面加上(前提是你的环境变量里已经配置过) -Dmaven.multiM ...

  2. Vue(三)之前端路由

    01-前端路由 1.前端路由的实现原理 vue+vue-router 主要来做单页面应用(Single Page Application) 为什么我们要做单页面应用? (1)传统的开发方式 url改变 ...

  3. 旋转数组的最小数字 - 剑指offer 面试题8

    题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...

  4. 通过this()调用有参构造方法

    使用原因:在通过无参构造方法实例化对象时,如果有属性可以设置默认值,可通过在无参构造方法中使用this()调用有参构造方法实现. this()需要写在无参构造方法的第一行! 例子:在没有给出小猫的名字 ...

  5. 设计模式——MVC MVP MVVM

    了解到Vue是MVVM前端框架, 中午就研究了一下MVVM,但要从MVC开始说起: M(Model):模型,提供数据: V(View):视图,负责显示: C(Controller):控制器,负责逻辑处 ...

  6. 动态规划-数位dp

    大佬讲的清楚 [https://blog.csdn.net/wust_zzwh/article/details/52100392] 例子 不要62或4 l到r有多少个数不含62或者4 代码 #incl ...

  7. 哈尔滨工程大学ACM预热赛

    https://ac.nowcoder.com/acm/contest/554#question A #include <bits/stdc++.h> using namespace st ...

  8. K8S、云计算、大数据、编程语言

    云计算.大数据.编程语言学习指南下载,100+技术课程免费学!这份诚意满满的新年技术大礼包,你Get了吗?-云栖社区-阿里云https://yq.aliyun.com/articles/691028 ...

  9. CentOS 7 安装配置带用户认证的squid代理服务器

    这里只简述搭建一个带用户认证的普通代理 一.安装 安装过程十分简便,只需要安装一下squid,一条命令搞定 yum install squid rpm -qa | grep squid squid-- ...

  10. JUnit测试提示Java.lang.Exception: No runnable methods

    网上一大堆都说,没写@Test,或者是,导包错误,= =然而我并没有发现我有这个毛病 = =最后终于找到罪魁祸首 Junit版本太低!!! Junit版本太低!!! Junit版本太低!!! = =因 ...