线段树/树状数组裸题,用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. 一直没有敢发的NOIP2018游记

    一直没有敢发的NOIP2018游记 NOIP2018游记 教练说知足是最好的,尽吾志而也不能及者,可以无悔矣.在这次考试中的表现令我还是十分满意的.(笑) D1 T0 我配置背得感觉很好,我考场上直接 ...

  2. [NOIP2018TG]旅行

    [NOIP2018TG]旅行 树很简单,对每个点sort儿子,贪心走就行了 基环树呢? 如果是1e5可能不太好做 但是5000的话枚举断边就可以\(n^2\)了 #include<bits/st ...

  3. where VS having

    where 和 having 的区别:        WHERE 子句不能包含聚集函数: 因为试图用聚集函数判断那些行输入给聚集运算是没有意义的.相反,HAVING 子句总是包含聚集函数    hav ...

  4. 4.6 基于STM32+MC20地图显示路径功能

    需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...

  5. Python基础(7)_闭包函数、装饰器

    一.闭包函数 闭包函数:1.函数内部定义函数,成为内部函数, 2.改内部函数包含对外部作用域,而不是对全局作用域名字的引用那么该内部函数成为闭包函数 #最简单的无参闭包函数 def func1() n ...

  6. 关于IDEA导出项目jar包/runnable jar

    将项目导出为jar包分为 runnable jar 与 普通jar包 一.导出为普通jar包 该jar包中只有项目源代码, java -cp wordcount.jar 用来运行普通jar包 1.打开 ...

  7. storage

    localStorage(本地存储),可以长期存储数据,没有时间限制,一天,一年,两年甚至更长,数据都可以使用. sessionStorage(会话存储),只有在浏览器被关闭之前使用,创建另一个页面时 ...

  8. pyhton3 os模块

    1 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 2 os.chdir("dirname") 改变当前脚本工作目录:相当于shell下cd 3 o ...

  9. android camera jni调用

    http://www.mamicode.com/info-detail-1002139.html how to compile  library of native camera for androi ...

  10. MySQL-LRU_List Free_List Flush_List

    关于 LRU_List ,Free_List,Flush_List的介绍:   LRU算法:(Latest Recent Used)最近最少使用      数据库的缓冲池通过LRU算法来进行管理.   ...