POJ3468--A Simple Problem with Integers(Splay Tree)
虽然有点难,但是这套题都挂了一个月了啊喂……
网上模板好多……最后还是抄了kuangbin聚聚的,毕竟好多模板都是抄他的,比较习惯……
POJ 3468
题意:给n个数,两种操作,区间整体加一个数,或者区间求和。
题解:把区间的前一个数挪到根,区间后一个数挪到根的右子树,根的右子树的左子树就是要处理的区间。。。
SplayTree是一个二叉排序树,它所保存的顺序是数字的编号,所以无论怎样旋转,编号的顺序都不会变。。。
在首尾各插入一个结点,这样求整个区间的时候也可以找到前一个数和后一个数。。。
照了别人的博客写了两遍,自己又裸敲一遍,还是错了好多细节,不过大概理解了。。。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = ;
int sz[N], ch[N][], pre[N];
int a[N];
ll sum[N], add[N], key[N];
int root, tot; void new_node(int &o, int fa, int k) {
o = ++tot;
sz[o] = ;
ch[o][] = ch[o][] = ;
pre[o] = fa;
sum[o] = key[o] = k;
add[o] = ;
} void push_up(int o) {
sum[o] = sum[ch[o][]] + sum[ch[o][]] + key[o];
sz[o] = sz[ch[o][]] + sz[ch[o][]] + ; // +1 !!
} void update(int o, int v) {
if (!o) return ;
add[o] += v;
key[o] += v;
sum[o] += (ll)sz[o]*v;
} void push_down(int o) {
if (add[o]) {
update(ch[o][], add[o]);
update(ch[o][], add[o]);
add[o] = ;
}
} void build(int &o, int l, int r, int fa) {
if (l > r) return;
int mid = (l+r) >> ;
new_node(o, fa, a[mid]);
build(ch[o][], l, mid-, o);
build(ch[o][], mid+, r, o);
push_up(o);
} void init(int n) {
root = tot = ;
sz[] = ch[][] = ch[][] = pre[] = ;
sum[] = add[] = key[] = ;
new_node(root, , -);
new_node(ch[root][], root, -);
build(ch[ch[root][]][], , n, ch[root][]);
push_up(ch[root][]);
push_up(root);
} void rotate(int o, int d) { // 0:left 1:right
int fa = pre[o];
push_down(fa);
push_down(o);
ch[fa][!d] = ch[o][d];
pre[ch[o][d]] = fa;
if (pre[fa]) ch[pre[fa]][ch[pre[fa]][]==fa] = o;
pre[o] = pre[fa];
ch[o][d] = fa;
pre[fa] = o;
push_up(fa);
} void splay(int o, int goal) {
push_down(o);
while (pre[o] != goal) {
if (pre[pre[o]] == goal) {
rotate(o, ch[pre[o]][] == o);
} else {
int fa = pre[o];
int d = (ch[pre[fa]][] == fa);
if (ch[fa][d] == o) {
rotate(o, !d);
rotate(o, d);
} else {
rotate(fa, d);
rotate(o, d);
}
}
}
push_up(o);
if (goal == ) root = o;
} int get_kth(int o, int k) {
push_down(o); //!!
int t = sz[ch[o][]] + ;
if (t == k) return o;
if (t > k) return get_kth(ch[o][], k);
return get_kth(ch[o][], k-t);
} ll query(int l, int r) {
splay(get_kth(root, l), );
splay(get_kth(root, r+), root);
return sum[ ch[ch[root][]][] ];
} void Add(int l, int r, int v) {
splay(get_kth(root, l), );
splay(get_kth(root, r+), root);
update(ch[ch[root][]][], v);
push_up(ch[root][]);
push_up(root);
} int main() {
//freopen("in.txt", "r", stdin);
int n, q;
while (~scanf("%d%d", &n, &q) && n) {
for (int i = ; i <= n; ++i) scanf("%d", a+i);
init(n);
char op[];
int x, y, z;
while (q--) {
scanf("%s%d%d", op, &x, &y);
if (*op == 'Q') {
printf("%lld\n", query(x, y));
} else {
scanf("%d", &z);
Add(x, y, z);
}
}
}
return ;
}
POJ3468--A Simple Problem with Integers(Splay Tree)的更多相关文章
- ACM学习历程——POJ3468 A Simple Problem with Integers(线段树)
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- poj3468 A Simple Problem with Integers (树状数组做法)
题目传送门 A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 1 ...
- A - 敌兵布阵 ——B - I Hate It——C - A Simple Problem with Integers(线段树)
C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...
- BZOJ3212: Pku3468 A Simple Problem with Integers(线段树)
3212: Pku3468 A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 2530 So ...
- Simple Problem with Integers(POJ 3486)
A Simple Problem with Integers Time Li ...
- poj3468 A Simple Problem with Integers(线段树区间更新)
https://vjudge.net/problem/POJ-3468 线段树区间更新(lazy数组)模板题 #include<iostream> #include<cstdio&g ...
- POJ3468 A Simple Problem with Integers(数状数组||区间修改的RMQ问题)
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of op ...
- poj3468 A Simple Problem with Integers(线段树/树状数组)
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- kuangbin专题七 POJ3468 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 ...
随机推荐
- 【BZOJ 3343 】 分块
3343: 教主的魔法 Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1. ...
- 李洪强iOS开发之静态库
iOS开发拓展篇—静态库 一.简单介绍 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的分类 根据源代码的公开情况,库可以分为2种类型 (1)开源库 公开源代码,能看到具体实现 ...
- VO,DTO,DO,PO的划分
实体类(VO,DTO,DO)的划分 经常会接触到VO,DO,DTO的概念,本文从领域建模中的实体划分和项目中的实际应用情况两个角度,对这几个概念进行简析. 得出的主要结论是:在项目应用中,VO对应 ...
- jquery的ajax向后台servlet传递json类型的多维数组
后台运行结果: 前台运行结果: ...
- POJ1850——Code(组合数学)
Code DescriptionTransmitting and memorizing information is a task that requires different coding sys ...
- WinAPI——UnhookWindowsHookEx - 卸掉钩子
UnhookWindowsHookEx( hhk: HHOOK {钩子句柄} ): BOOL; {True/False}
- 关于捕获键盘信息的processDialogkey方法2--具体应用
自定义控件里的keydown方法无法捕获所有的按键消息的处理方法1(自定义控件里的keydown方法无法获取的键值如上下左右键等) 处理办法具体如下: 1.首先在自定义控件UserControl1中重 ...
- poj2886Who Gets the Most Candies? (约瑟夫环)
http://poj.org/problem?id=2886 单点更新 初始位置都是1 如果这个人出去 位置变为0 利用线段树求区间k值 k值的计算如下 如果这个数值是负的 那么下一个人的就是((k- ...
- poj2186Popular Cows(强连通分量)
http://poj.org/problem?id=2186 用tarjan算出强连通分量的个数 将其缩点 连成一棵树 则题目所求即变成求出度为0 的那个节点 在树中是唯一的 即树根 #includ ...
- CSS那些事儿-阅读随笔1(CSS简介与选择符)
最近开始详细钻研CSS有关的知识,参考资料是<CSS那些事儿>.将把在此过程中的收获进行记录,方便以后的学习. 一.CSS简介 1.什么是CSS CSS全称为Cascading Style ...