Problem 平衡树 splay2

题目大意

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

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

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

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

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

解题分析

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

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

参考程序

 #include <bits/stdc++.h>
using namespace std; int tag=; struct node{
int id,num;
long long lazy,val,sum;
node *left,*right,*father;
node(int id_=,long long val_=,int num_=,long long lazy_=,long long sum_=,node* father_=NULL,node* left_=NULL,node* right_=NULL)
{
id=id_; val=val_; num=num_; lazy=lazy_; sum=sum_;
father=father_; left=left_; right=right_;
}
}*rt,*t1,*t2; void search(node *now)
{
cout<<now->id; cout<<" val= "<<now->val<<" sum= "<<now->sum<<" num= "<<now->num<<" lazy= "<<now->lazy;
if (now->left) cout<<" lson: "<<now->left->id;
if (now->right) cout<<" rson: "<<now->right->id;
cout<<endl;
if (now->left) search(now->left);
if (now->right) search(now->right);
} void pushup(node* x)
{
x->sum=x->val; x->num=;
if (x->left) x->sum+=x->left->sum,x->num+=x->left->num;
if (x->right) x->sum+=x->right->sum,x->num+=x->right->num;
} void pushdown(node* x)
{
if (x->lazy)
{
node *l = x->left,*r = x->right;
if (l)
{
l->lazy += x->lazy;
l->val += x->lazy;
l->sum += x->lazy * l->num;
}
if (r)
{
r->lazy += x->lazy;
r->val += x->lazy;
r->sum += x->lazy * r->num;
}
x->lazy = ;
}
} void right(node* x,node* &rt)
{
node *y=x->father,*z=y->father;
if (y==rt) rt=x;
else if (z->left==y) z->left=x; else z->right=x; //需要判断是左右孩子
x->father=z; y->father=x; if (x->right) x->right->father=y; //防止对空指针进行操作
y->left=x->right; x->right=y;
pushup(y); pushup(x);
} void left(node* x,node* &rt)
{
node *y=x->father,*z=y->father;
if (y==rt) rt=x;
else if (z->left==y) z->left=x; else z->right=x;
x->father=z; y->father=x; if (x->left) x->left->father=y;
y->right=x->left; x->left=y;
pushup(y); pushup(x);
} void splay(node* x,node* &rt)
{
while (x!=rt)
{
node *y=x->father, *z=y->father;
if (y==rt)
{
if (x==y->left) right(x,rt);
else left(x,rt);
}
else
{
if (y==z->left)
if (x==y->left) { right(y,rt); right(x,rt); }
else { left(x,rt); right(x,rt); }
else
if (x==y->right) { left(y,rt); left(x,rt); }
else { right(x,rt); left(x,rt); }
}
}
} void insert(int id,int val,node* &now,node *last)
{
if (now==NULL)
{
now=new node(id,val,,,val,last);
splay(now,rt);
return;
}
pushdown(now);
if (id < now->id) insert(id,val,now->left,now); else insert(id,val,now->right,now);
//else还是要加的 返回的时候树的形态已经改变了
} void find_1(int id,node *x)
{
if (x==NULL) return;
pushdown(x);
if (x->id>=id) find_1(id,x->left);
else {t1=x; find_1(id,x->right);}
} void find_2(int id,node *x)
{
if (x==NULL) return;
pushdown(x);
if (x->id<=id) find_2(id,x->right);
else {t2=x; find_2(id,x->left);}
} void del(int l,int r)
{
t1=t2=NULL;
find_1(l,rt); splay(t1,rt);
find_2(r,rt->right); splay(t2,rt->right);
rt->right->left=NULL;
pushup(rt->right); pushup(rt);
} void add(int l,int r,int val)
{
t1=t2=NULL;
find_1(l,rt); splay(t1,rt);
find_2(r,rt->right); splay(t2,rt->right);
if (rt->right->left)
{
rt->right->left->lazy += val;
rt->right->left->sum += 1ll* val * rt->right->left->num;
rt->right->left->val += val;
}
pushup(rt->right); pushup(rt);
} long long query(int l,int r)
{
t1=t2=NULL;
find_1(l,rt); splay(t1,rt);
find_2(r,rt->right); splay(t2,rt->right);
if (rt->right->left)
return rt->right->left->sum;
else return ;
} int main()
{
int n;
rt=NULL;
scanf("%d",&n);
insert(<<,,rt,NULL); insert(-<<,,rt,NULL);
for (int i=;i<=n;i++)
{
char s[]; int x,y,z;
scanf("%s%d%d",s,&x,&y);
if (s[]=='I') insert(x,y,rt,NULL);
if (s[]=='D') del(x,y);
if (s[]=='M')
{
scanf("%d",&z);
add(x,y,z);
}
if (s[]=='Q') cout<<query(x,y)<<endl;
}
}

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. Spark之RDD的定义及五大特性

    RDD是分布式内存的一个抽象概念,是一种高度受限的共享内存模型,即RDD是只读的记录分区的集合,能横跨集群所有节点并行计算,是一种基于工作集的应用抽象. RDD底层存储原理:其数据分布存储于多台机器上 ...

  2. python自动化学习笔记11-自动化测试UTP框架

    前面基本的unittest及ddt已经学过了,现在我们系统把这些知识结合起来,写一个简单的UTP自动化测试框架: 我们先来建基础目录,首先新建一个项目,项目下建父目录UTP,conf目录,用来存放配置 ...

  3. [Usaco2018 Open]Milking Order

    Description Farmer John的N头奶牛(1≤N≤10^5),仍然编号为1-N,正好闲得发慌.因此,她们发展了一个与Farmer John每天早上为她们挤牛奶的时候的排队顺序相关的复杂 ...

  4. Snackbar:用它来替换Toast 显示短提示

    简介 Snackbar 它是Toast的子类.主要用来提示短暂的提示信息后,然后它自动消失. 它寄生在普通view上,具有一些基本功能. 它寄生在 CoordinatorLayout 时,有以下两个特 ...

  5. 【CImg】基本像素操作

    继openCV之后接触的又一个C++视觉库——短小精干的CImg 刚开始接触的时候真的是..几乎无从下手,网上资料比较少,但发现有一篇非常有用的中文手册:http://wenku.baidu.com/ ...

  6. Extensions can add new functionality to a type, but they cannot override existing functionality.

    Extensions can add new functionality to a type, but they cannot override existing functionality.

  7. 搭建Cookie池

    很多时候我们在对网站进行数据抓取的时候,可以抓取一部分页面或者接口,这部分可能没有设置登录限制.但是如果要抓取大规模数据的时候,没有登录进行爬取会出现一些弊端.对于一些设置登录限制的页面,无法爬取对于 ...

  8. 00The C Programming Language

    The C Programming Language C语言是一门面向过程.抽象化的通用程序设计语言,广泛应用于底层开发.C语言能以简易的方式编译.处理低级存储器.C语言是仅产生少量的机器语言以及不需 ...

  9. API Studio 5.1.2 版本更新:加入全局搜索、支持批量测试API测试用例、读取代码注解生成文档支持Github与码云等

    最近在EOLINKER的开发任务繁重,许久在博客园没有更新产品动态了,经过这些日子,EOLINKER又有了长足的进步,增加了更多易用的功能,比如加入全局搜索.支持批量测试API测试用例.读取代码注解生 ...

  10. MONO Design创建电信3D机房

    前面我们简单介绍了下一分钟创建3D机房,实则mono Design的功能远远不止这些,试想一下,如果我们花上10分钟来创建一个电信机房,那么MONO design又会给我们带来什么样的惊喜呢? 我们从 ...