poj3468 splay(成段跟新 区间求和)
用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(成段跟新 区间求和)的更多相关文章
- UESTC-1057 秋实大哥与花(线段树+成段加减+区间求和)
秋实大哥与花 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit St ...
- 线段树(成段更新,区间求和lazy操作 )
hdu1556 Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- 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 ...
- POJ 3468.A Simple Problem with Integers-线段树(成段增减、区间查询求和)
POJ 3468.A Simple Problem with Integers 这个题就是成段的增减以及区间查询求和操作. 代码: #include<iostream> #include& ...
- 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 ...
- POJ 3225.Help with Intervals-线段树(成段替换、区间异或、简单hash)
POJ3225.Help with Intervals 这个题就是对区间的各种操作,感觉这道题写的一点意思都没有,写到后面都不想写了,而且更神奇的是,自己的编译器连结果都输不出来,但是交上就过了,也是 ...
- poj_3468线段树成段更新求区间和
#include<iostream> #include<string.h> #include<cstdio> long long num[100010]; usin ...
- 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和
poj3468 A Simple Problem with Integers 题意:O(-1) 思路:O(-1) 线段树功能:update:成段增减 query:区间求和 Sample Input 1 ...
- poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)
转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...
随机推荐
- DFS cdoevs 3100 蜗牛
cdoevs 3100 蜗牛 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 萨丽·斯内尔(Sally Snail,蜗牛)喜欢在 ...
- [ZZ]Sign Up for the First-Ever Appium Roadshow on August 20th in New York City
http://sauceio.com/index.php/2014/07/appium-roadshow-nyc/?utm_source=feedly&utm_reader=feedly&am ...
- eclipse菜单解释及中英对照《二》
上篇文章主要介绍了eclipse中每个大的标题下的中英文及其用法. 感谢http://blog.csdn.net/li_jinjian2005/article/details/2831641这个博主. ...
- eclipse luna maven失效的原因
昨天发现单位里的eclipse中的maven直接不显示了,不能在 Windows-Preference 中显示maven 也不能新建maven工程,也不能maven-update,连STS(Sprin ...
- Mecanim的Retargeting和BodyMask
Retargeting(动画重定向) 文档 http://game.ceeger.com/Manual/Retargeting.html 介绍 Mecanim 的最强大的功能之一,重定目标的仿人机器人 ...
- 大话Git
Git是什么 Git是一个分布式版本控制系统.它可以很方便的记录你的每一次变动,而不需要每次都备份,还能让你和他人很方便的协同开发.这样你每次做了什么改动,瞄一眼就一清二楚了. -- 安装Git 从官 ...
- 查询Sqlserver数据库死锁的一个存储过程(转)
链接 :http://www.cnblogs.com/mzhanker/archive/2011/06/04/2072739.html 使用sqlserver作为数据库的应用系统,都避免不了有时候会产 ...
- MySQL 约束的讲解
MySQL 约束 作用:保证数据的完整性和一致性按照约束的作用范围分为:表级约束和行级约束.常见的约束类型包括: Not null(非空约束) Primary key (主键约束) Unique ke ...
- [tools]google神器浏览器下载
google神器下载 这是一款优化了的google浏览器 http://www.ccav1.me/chromegae.html
- c语言 数组名是常量指针
//数组名是常量指针 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include ...