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 ...
随机推荐
- CentOS7.2安装总结
第一次自己写文章,想想还有点小激动呢.折腾了大半天,终于在一个没用的台式机上面装了个mini版的CentOS7.2.写这篇文章也是做个记载,要是以后再装要注意了. 一.安装过程 采用U盘安装.最初是准 ...
- 2014 Super Training #9 E Destroy --树的直径+树形DP
原题: ZOJ 3684 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3684 题意: 给你一棵树,树的根是树的中心(到其 ...
- Fix "Missing Scripts"
一.Missing Scripts(脚本引用丢失) 请看下面的两张图的Warn(脚本引用丢失),在某些情况下我们会遇到这个警告. 二.解决办法 参考资料 http://unitygems.com/la ...
- java11-2 String面试题
package cn.itcast_02; /* * String s = new String(“hello”)和String s = “hello”;的区别? * 有.前者会创建2个对象,后者创建 ...
- 使用clone( )和Cloneable接口
由Object类定义的绝大部分方法在本书其他部分讨论.而一个特别值得关注的方法是clone( ).clone( )方法创建调用它的对象的一个复制副本.只有那些实现Cloneable接口的类能被复制. ...
- Python-操作Memcache、Redis、RabbitMQ、
Memcache 简述: Memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的.需要 ...
- OXM
O/X Mapper 是什么? Spring 3.0 的一个新特性是 O/X Mapper.O/X 映射器这个概念并不新鲜,O 代表 Object,X 代表 XML.它的目的是在 Java 对象(几乎 ...
- 谷歌验证 (Google Authenticator) 的实现原理是什么?
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:徐小花链接:http://www.zhihu.com/question/20462696/answer/18731073来源: ...
- 解决SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问的方法
1.开启Ad Hoc Distributed Queries组件,在sql查询编辑器中执行如下语句: reconfigure reconfigure 2.关闭Ad Hoc Distributed Qu ...
- 求时间差的sql语句。 比如如下数据
msisdn createtime closetime138 2011-5-17 15:30:00:000 2011-5-17 15:30:00:530138 2011-5-17 15:40:00:0 ...