线段树/树状数组裸题,用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. Nuxt使用scss

    Nuxt中使用scss也很简单,分简单的几步就OK 一.安装scss依赖 用IDE打开项目,在Terminal里通过 npm i node-sass sass-loader scss-loader - ...

  2. 两个offer如何做选择?年薪20万vs年薪15万

    (附注:本文转载于:http://www.eoeandroid.com/thread-296678-1-1.html) 前些天和一个年轻的朋友谈跳槽.朋友说她需要在两个offer里面做选择.一个是年薪 ...

  3. 免费 SSL 安全证书

    为了保证网上传输信息的安全而在自己的 Linode VPS 上部署 SSL 加密服务.商业 CA 较贵,所以使用了自己签发的 CA.网友神爱的留言提到了 StartSSL 的免费 CA,稍做了一些调查 ...

  4. substring splice

    返回start到end之前 不包括end stringObject.substring(start,end) (不接受负数) stringObject.slice(start,end) start起始 ...

  5. Django 进阶篇之 Form验证

    Django Form验证 在实际的生产环境中比如登录和验证的时候,我们一般都使用Jquery+ajax来判断用户的输入是否为空,假如JS被禁用的话,咱们这个认证屏障是不是就消失了呢?(虽然一般不会禁 ...

  6. Kattis - prva 【字符串】

    题意 从上到下 或者 从左到右 组成的长度 >= 2 的字符串 如果遇到 # 就断掉 输出 字典序最小的那一个 思路 只要从上到下 和从左到右 分别遍历一遍,将 长度 >= 2 的字符串 ...

  7. 每天一个Linux命令(60)ip命令

        ip命令是Linux下较新的功能强大的网络配置工具.     (1)用法:     用法:  ip  [OPTIONS]  OBJECT  [COMMAND [ARGUMENTS]]     ...

  8. $Android自定义控件在不同状态下的属性

    在写代码的时候,有时候需要控件在不同状态下显示不同的外观,比如在按钮按下的时候要变颜色,EditText获取焦点时候边框要变颜色等.那么下面就来梳理一下这些是怎么实现的. (一)按钮按下时候变颜色 1 ...

  9. $Android制作和使用Nine-Patch图片

    Nine-Patch图片是一种经过特殊处理的png图片,能够指定图片的哪些区域可以被拉伸而哪些区域不可以. (一)普通图片被拉伸时的缺陷 有如下xml文件,其中子LinearLayout的背景图片设置 ...

  10. 06_Hadoop配置伪分布式模式详解

    查看IP地址,设为手动模式: 配置hadoop用户sudo权限 su切换到root身份,配置vim /etc/sudoers文件,加入 hadoop ALL=(root)NOPASSWD:ALL    ...