虽然有点难,但是这套题都挂了一个月了啊喂……

网上模板好多……最后还是抄了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)的更多相关文章

  1. 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 ...

  2. poj3468 A Simple Problem with Integers (树状数组做法)

    题目传送门 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 1 ...

  3. A - 敌兵布阵 ——B - I Hate It——C - A Simple Problem with Integers(线段树)

    C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...

  4. BZOJ3212: Pku3468 A Simple Problem with Integers(线段树)

    3212: Pku3468 A Simple Problem with Integers Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 2530  So ...

  5. Simple Problem with Integers(POJ 3486)

                                                                  A Simple Problem with Integers Time Li ...

  6. poj3468 A Simple Problem with Integers(线段树区间更新)

    https://vjudge.net/problem/POJ-3468 线段树区间更新(lazy数组)模板题 #include<iostream> #include<cstdio&g ...

  7. 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 ...

  8. poj3468 A Simple Problem with Integers(线段树/树状数组)

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  9. 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 ...

随机推荐

  1. 一个只需要点 「下一步」就完成监控 Windows

    Cloud Insight 此前已然支持 Linux 操作系统,支持20多中数据库中间件等组件,多种操作,多种搭配,服务器监控玩的其乐无穷啊!但想想还有许多 Windows 的小伙伴没有体验过,所以在 ...

  2. Codeigniter开发技巧:连接多个数据库(可实现DB读写分离)

    在开发中,我们有时候会遇到在同一程序中链接多个数据库的需求,这对Codeigniter框架来说是很简单的,我们只需要在 database.php文件中配置少许参数即可. 默认情况下,CI配置的是链接一 ...

  3. FF浏览器来帮助我们录制脚本

    有时我们录制一个页面的脚本,我们需要知道这个页面哪些请求是耗时最大的?这个时候FF浏览器的网络分析功能就可以派上用场了,打开火狐浏览器按F12: 点击重新载入,可以看到下面的信息: 看到最耗时的操作了 ...

  4. POJ2115——C Looooops(扩展欧几里德+求解模线性方程)

    C Looooops DescriptionA Compiler Mystery: We are given a C-language style for loop of type for (vari ...

  5. Android之AlertDialog.Builder详解

    import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; ...

  6. 50个非常有用的PHP工具

    PHP是使用最为广泛的开源服务器端脚本语言之一,当然PHP并不是速度最快的,但它却是最常用的脚本语言.这里有50个有益的PHP工具,可以大大提高你的编程工作: 调试工具 Webgrind Xdebug ...

  7. POJ3608(旋转卡壳--求两凸包的最近点对距离)

    题目:Bridge Across Islands 分析:以下内容来自:http://blog.csdn.net/acmaker/article/details/3178696 考虑如下的算法, 算法的 ...

  8. JavaBean个人总结

    JavaBean在JSP程序中的应用 JavaBean是为Java语言设计的软件组件模型,具有可重复使用和跨平台的特点.可以通过JavaBean来封装业务逻辑,进行数据库操作等,从而很好的实现业务逻辑 ...

  9. 函数fsp_seg_inode_page_find_free

    /**********************************************************************//** Looks for an unused segm ...

  10. bzoj1061: [Noi2008]志愿者招募

    线性规划与费用流.http://www.cnblogs.com/iiyiyi/p/5616080.html.数组范围开错了!!!然后2.31-1=0x7fffffff!=0x7f7f7f7f. 开始以 ...