线段树/树状数组裸题,用splay写

splay也是基本操作pushup pushdown

话说我就是找不到全一点的模板,我自己写又全是bug,导致代码风格一直变来变去= =

关键是建树和区间操作(区间和,区间翻转,区间合并这几个写法都很难统一)

#include<map>
#include<set>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1 using namespace std;
using namespace __gnu_cxx; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f; struct Node{
Node *ch[],*fa;
int id,s,v,add;
ll sum;
void pushdown()
{
if(add)
{
if(ch[])
{
ch[]->v += add;
ch[]->add += add;
ch[]->sum += (ll)add*ch[]->s;
}
if(ch[])
{
ch[]->v += add;
ch[]->add += add;
ch[]->sum += (ll)add*ch[]->s;
}
add=;
}
}
void pushup()
{
s = ch[]->s + ch[]->s + ;
sum = v + ch[]->sum + ch[]->sum;
}
};
Node *root,NODE[N],*null=&NODE[];
int num[N],n,top;
struct SplayTree{
void Rotate(Node *x,int f)
{
Node* y= x->fa;
y->pushdown();x->pushdown();
y->ch[!f] = x->ch[f];
x->ch[f]->fa = y;
x->fa = y->fa;
if(x->fa!=null)y->fa->ch[y->fa->ch[]==y]=x;
x->ch[f] = y;
y->fa=x;
y->pushup();
}
void splay(Node* x,Node* goal)//把x splay到goal下面
{
x->pushdown();
while(x->fa!=goal)
{
if(x->fa->fa == goal)Rotate(x,x->fa->ch[]==x);
else
{
Node *y=x->fa,*z=y->fa;
int f=(z->ch[]==y);
y->ch[f]==x ? Rotate(x,!f):Rotate(y,f);
Rotate(x,f);
}
}
x->pushup();
if(goal==null)root=x;
}
void RTO(int k,Node *goal)//把排名为k的节点splay到goal下面
{
Node *x=root;
x->pushdown();
while(x->ch[]->s+!=k)
{
if(k < x->ch[]->s+)x=x->ch[];
else
{
k -= x->ch[]->s+;
x = x->ch[];
}
x->pushdown();
}
splay(x,goal);
}
Node* newnode(Node* fa,int v)
{
Node *x=&NODE[++top];
x->id=top;
x->ch[]=x->ch[]=null;
x->s=;
x->v=x->sum=v;
x->add=;
x->fa=fa;
return x;
}
void build(Node* &x,int l,int r,Node* fa)
{
if(l>r)return ;
int m=(l+r)>>;
x=newnode(fa,num[m]);
build(x->ch[],l,m-,x);
build(x->ch[],m+,r,x);
x->pushup();
}
void debug(Node* x)
{
if(x!=null)
{
debug(x->ch[]);
cout<<x->v<<" "<<x->sum<<endl;
debug(x->ch[]);
}
}
void init(int n)
{
top=;
null->id=;
null->fa = null->ch[] = null->ch[] = NULL;
null->s = null->add = null->v = null->sum = ;
root = newnode(null,-);
root->ch[] = newnode(root,-);
root->s=;
for(int i=;i<=n;i++)scanf("%d",&num[i]);
build(root->ch[]->ch[],,n,root->ch[]);
root->ch[]->pushup();root->pushup();
}
void update()
{
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
RTO(l,null);
RTO(r+,root);
root->ch[]->ch[]->add += c;
root->ch[]->ch[]->v += c;
root->ch[]->ch[]->sum += (ll)c*root->ch[]->ch[]->s;
}
void query()
{
int l,r;
scanf("%d%d",&l,&r);
RTO(l,null);
RTO(r+,root);
printf("%lld\n",root->ch[]->ch[]->sum);
}
}spt;
int main()
{
int n,q;
scanf("%d%d",&n,&q);
spt.init(n);
while(q--)
{
char s[];
scanf("%s",s);
if(s[]=='Q')spt.query();
else spt.update();
}
return ;
}
/************
10 5
1 5 64 8 2 47 6 4 6 7
************/

POJ3468 splay的更多相关文章

  1. poj3468 splay(成段跟新 区间求和)

    用splay做了一遍. 建树时是按照数列序号从小到大排好的,每个节点左子树的序号小于右子树的序号及这个节点本身.由于查询[l,r]要伸展l-1,r+1所以我们要多加2个结点,保证边界处理时不出问题.由 ...

  2. POJ3468/splay树/成段更新

    板子题,正在努力看懂板子.. http://blog.csdn.net/acm_cxlove/article/details/7815019 http://www.cnblogs.com/kuangb ...

  3. POJ-3468 A Simple Problem with Integers Splay Tree区间练习

    题目链接:http://poj.org/problem?id=3468 以前用线段树做过,现在用Splay Tree A了,向HH.kuangbin.cxlove大牛学习了各种Splay各种操作,,, ...

  4. Splay POJ3468(老题新做)

    A Simple Problem with Integers Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d ...

  5. POJ3468:A Simple Problem with Integers (线段树||树状数组||Splay解决基本问题的效率对比)

    You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of op ...

  6. POJ 3468 A Simple Problem with Integers (splay tree入门)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 47944   ...

  7. poj 3468 Splay 树

    大二上的时候.写过一个AVL的操作演示,今天一看Splay.发现和AVL事实上一样,加上线段树的基础,懒惰标记什么都知道.学起来轻松很多哦 我參考的模板来自这里  http://blog.csdn.n ...

  8. BZOJ 1251: 序列终结者 [splay]

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3778  Solved: 1583[Submit][Status][Discu ...

  9. [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)

    Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或 ...

随机推荐

  1. 洛谷 P4819 [中山市选]杀人游戏

    洛谷 题目就是让我们在DAG中找到一些点,覆盖所有点. 因为是DAG,可以想到tarjan缩一下点.假设我们需要找x个点,那么答案就是(n-x)/n. 我们怎么选点呢? 敏锐的我们很快就能想到,直接选 ...

  2. python函数回顾:min()

    描述 min() 方法返回给定参数的最小值,参数可以为序列. 语法 以下是 min() 方法的语法: min( x, y, z, .... ) 参数 x -- 数值表达式. y -- 数值表达式. z ...

  3. Python中的魔术(双下划线'__xxx__')方法详解

    介绍 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,中文称『魔术方法』,例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中 ...

  4. SPDY

    转载SPDY 是什么 SPDY 是 Google 开发的基于传输控制协议 (TCP) 的应用层协议 ,开发组正在推动 SPDY 成为正式标准(现为互联网草案).SPDY 协议旨在通过压缩.多路复用和优 ...

  5. LATEX教程(二)

    插入图片 \documentclass{article} \usepackage{graphicx} \usepackage{Ctex} \title{插入图片} \author{yif} \begi ...

  6. App的开发过程

    不同的项目管理模式或许会有完全不同的流程步骤.但是专业性几乎是保证产品质量的唯一准则. App的开发过程主要分为以下阶段,本文会按顺序为大家简单地说明: 1.需求梳理.分析 2.产品原型图绘制 3.U ...

  7. 20170520 BADI增强学习

    一.要求:Tcode:FF_5 导入数据运行时,产生财务凭证之前修改某些字段值.Exmp:FEBRE-VWEZWBKPF-XBLNRFEBEP-CHECTBSEG-ZUONR there is a b ...

  8. MapInfo 文件格式说明

    MapInfo 文件格式说明(id.map.tab.dat) (1). 属性数据的表结构文件.TAB 属性数据表结构文件定义了地图属性数据的表结构,包括字段数.字段名称.字段类型和字段宽度.索引字段及 ...

  9. LeetCode:整数转罗马数字【12】

    LeetCode:整数转罗马数字[12] 题目描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 10 ...

  10. Python 1 数据类型的操作

    一.数字(Number) 1.数学函数: 函数 返回值 ( 描述 ) abs(x) 返回数字的绝对值,如abs(-10) 返回 10 ceil(x) 返回数字的上入整数,如math.ceil(4.1) ...