用splay做了一遍。

建树时是按照数列序号从小到大排好的,每个节点左子树的序号小于右子树的序号及这个节点本身。
由于查询[l,r]要伸展l-1,r+1所以我们要多加2个结点,保证边界处理时不出问题。由于这样每次查找l-1时,
要找的应该是l(r+1也是找r+2)。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define ll __int64
#define key_value ch[ch[root][1]][0]
using namespace std;
const int MAXN=;
int pre[MAXN],ch[MAXN][],key[MAXN],tot1,root;
int siz[MAXN],tot2,a[MAXN],n,s[MAXN];
ll lazy[MAXN],sum[MAXN]; void Treavel(int x)
{
if(x)
{
Treavel(ch[x][]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d add=%2d sum=%I64d\n",x,ch[x][],ch[x][],pre[x],siz[x],key[x],lazy[x],sum[x]);
Treavel(ch[x][]);
}
}
void debug()
{
printf("root:%d\n",root);
Treavel(root);
} void Newnode(int &rt,int father,int k)
{
if(tot2)
rt = s[--tot2];
else
rt = ++tot1;
pre[rt] = father;
key[rt] = k;
siz[rt] = ;
lazy[rt] = ;
ch[rt][] = ch[rt][] = ;
}
void pushup(int rt)
{
siz[rt] = siz[ch[rt][]] + siz[ch[rt][]] + ;
sum[rt] = sum[ch[rt][]] + sum[ch[rt][]] + key[rt];
}
void pushdown(int rt)
{
if(lazy[rt]){
lazy[ch[rt][]] += lazy[rt];
lazy[ch[rt][]] += lazy[rt];
key[ch[rt][]] += lazy[rt];
key[ch[rt][]] += lazy[rt];
sum[ch[rt][]] += (ll)siz[ch[rt][]]*lazy[rt];
sum[ch[rt][]] += (ll)siz[ch[rt][]]*lazy[rt];
lazy[rt] = ;
}
}
void build(int &rt,int l,int r,int father)
{
if(l > r)
return ;
int m = (l+r)/;
Newnode(rt,father,a[m]);
build(ch[rt][],l,m-,rt);
build(ch[rt][],m+,r,rt);
pushup(rt);
}
void Init()
{
int i,j;
for(i=; i<=n; i++){
scanf("%d",&a[i]);
}
root = tot1 = tot2 = ;
ch[root][] = ch[root][] = key[root] = siz[root] = lazy[root] = pre[root] = sum[root] = ;
Newnode(root,,-);
Newnode(ch[root][],root,-);//头尾各加入一个点
build(key_value,,n,ch[root][]);//让所有数据夹在这两个点之间 由于树的结构 所以在ch[ch[root][1]][0]
pushup(ch[root][]);
pushup(root);
}
void Rotate(int rt,int kind)
{
int y = pre[rt];
pushdown(y);
pushdown(rt);
ch[y][!kind] = ch[rt][kind];
pre[ch[rt][kind]] = y;
if(pre[y]){
ch[pre[y]][ch[pre[y]][]==y] = rt;
}
pre[rt] = pre[y];
ch[rt][kind] = y;
pre[y] = rt;
pushup(y);
}
void splay(int rt,int goal)
{
pushdown(rt);
while(pre[rt] != goal)
{
if(pre[pre[rt]] == goal){
Rotate(rt,ch[pre[rt]][]==rt);
}
else {
int y = pre[rt];
int kind = ch[pre[y]][]==y;
if(ch[y][kind] == rt){
Rotate(rt,!kind);
Rotate(rt,kind);
}
else {
Rotate(y,kind);
Rotate(rt,kind);
}
}
}
pushup(rt);
if(goal == )
root = rt; }
int Get_kth(int rt,int k)
{
pushdown(rt);
int t = siz[ch[rt][]] + ;
if(t == k){
return rt;
}
else if(t > k){
return Get_kth(ch[rt][],k);
}
else
return Get_kth(ch[rt][],k-t);
}
void updata(int l,int r,int v)
{
splay(Get_kth(root,l),);
splay(Get_kth(root,r+),root);
key[key_value] += v;
lazy[key_value] += v;
sum[key_value] += (ll)v*siz[key_value];
}
ll query(int l,int r)
{
splay(Get_kth(root,l),);//由于开始的时候多添加了2个结点,所以编号都是在这2个结点之间的 所以查询的时候都要大1
splay(Get_kth(root,r+),root);
return sum[key_value];
}
int main()
{
int i,j,q;
while(~scanf("%d%d",&n,&q))
{
Init();
//debug();
char s[];
while(q--)
{
scanf("%s",s);
if(s[] == 'C'){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
updata(x,y,z);
}
else {
int x,y;
scanf("%d%d",&x,&y);
printf("%I64d\n",query(x,y));
}
}
}
}

poj3468 splay(成段跟新 区间求和)的更多相关文章

  1. UESTC-1057 秋实大哥与花(线段树+成段加减+区间求和)

    秋实大哥与花 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit St ...

  2. 线段树(成段更新,区间求和lazy操作 )

    hdu1556 Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  3. POJ-3468 A Simple Problem with Integers (区间求和,成段加减)

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

  4. POJ 3468.A Simple Problem with Integers-线段树(成段增减、区间查询求和)

    POJ 3468.A Simple Problem with Integers 这个题就是成段的增减以及区间查询求和操作. 代码: #include<iostream> #include& ...

  5. poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)

    题目链接 题意: 只有这两种操作 C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.&quo ...

  6. POJ 3225.Help with Intervals-线段树(成段替换、区间异或、简单hash)

    POJ3225.Help with Intervals 这个题就是对区间的各种操作,感觉这道题写的一点意思都没有,写到后面都不想写了,而且更神奇的是,自己的编译器连结果都输不出来,但是交上就过了,也是 ...

  7. poj_3468线段树成段更新求区间和

    #include<iostream> #include<string.h> #include<cstdio> long long num[100010]; usin ...

  8. 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和

    poj3468 A Simple Problem with Integers 题意:O(-1) 思路:O(-1) 线段树功能:update:成段增减 query:区间求和 Sample Input 1 ...

  9. poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)

    转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...

随机推荐

  1. JavaWeb学习----JSP脚本元素、指令元素、动作元素

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  2. 第四章 在MVC4.0中对脚本以及样式表的引用变化

    原文:http://www.cnblogs.com/xdotnet/archive/2012/07/21/aspnet40_webpage20.html 一.可以直接使用“~”,而无需使用Href对象 ...

  3. 工作流模式与K2实现- (1)

    背景 工作流产品众多,而它们之间又缺乏统一的标准,使得不同的产品之间很难实现协同工作.为了解决这一问题,工作流管理联盟(WFMC)于1993 年成立,并提出了工作流参考模型,制定了五个标准接口. 其中 ...

  4. C语言 原码--反码--补码

    //原码,反码,补码 #include<stdio.h> #include<stdlib.h> //数值的表示方法——原码.反码和补码 //原码:最高位为符号位,其余各位为数值 ...

  5. Discuz! X的CSS加载机制

    首先,每个页面都会加载以下两个css,data/cache/style_1_common.css和data/cache/style_1_forum_index.css.先讲讲这两个文件名的命名规则:第 ...

  6. [转]World Wind Java开发之五——读取本地shp文件

    World Wind Java 使用IconLayer图层类表现点和多点数据,使用RenderableLayer图层表现线和面数据,一个图层只能对应一组shape文件.World Wind Java首 ...

  7. Oracle 组织架构(转)

    原文地址:Oracle 组织架构 我们先来看一下实际生活中的集团组织架构. 下图是一个典型的投资集团组织架构. 集团在各个国家有独立的法人. 每个法人会负责若干个业务进行,比如石油开采,汽车制造,软件 ...

  8. python 3 安装 scrapy 并运行成功

    今天,python 3 安装 scrapy, 并运行成功.特此纪念! 我的环境:windows 10(64位) + python 3.5.2(64位) 其中几个要点说明一下: 1.有几个依赖库需要事先 ...

  9. LeetCode 笔记24 Palindrome Partitioning II (智商碾压)

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  10. 《信息安全系统设计基础》实验五 简单嵌入式WEB服务器实验

    实验报告链接:http://www.cnblogs.com/lx20145332/p/6058790.html