POJ 3468.A Simple Problem with Integers 解题报告
用树状数组和线段树会比较简单,这里用这道题来学习Splay。
第一次写,代码比较丑
- /*
- 初始化添加一个key值足够大的结点
- 保证每个需要的结点都有后继
- */
- #include <iostream>
- #include <cstdio>
- #define ll long long
- using namespace std;
- const int MAXN = , INF = 0x7fffffff;
- struct node {
- //需要的记录信息
- ll key, val, sum, lazy, Size, Cnt;
- //指向儿子和父亲的指针
- node *ch[], *pre;
- node() {pre = ch[] = ch [] = ; Size = ; key = ;}
- node (ll key) : key (key) {pre = ch[] = ch[] = ; Size = , Cnt = , lazy = ;}
- void Csize() {
- Size = Cnt;
- if (ch[] != NULL) Size += ch[]->Size;
- if (ch[] != NULL) Size += ch[]->Size;
- }
- void Csum() {
- sum = val;
- if (ch[] != NULL) sum += ch[]->sum + ch[]->Size * ch[]->lazy;
- if (ch[] != NULL) sum += ch[]->sum + ch[]->Size * ch[]->lazy;
- }
- } nil (), *NIL = &nil;
- struct Splay {
- node *root, nod[MAXN];
- int ncnt;//计算key值不同的结点数,已去重
- Splay() {
- ncnt = ;
- root = & (nod[ncnt++] = node (INF) );
- root->pre = NIL;
- root->val = root->sum = ;
- }
- void Push_Down (node *x) {
- if (x->lazy != ) {
- if (x->ch[] != NULL) x->ch[]->lazy += x->lazy;
- if (x->ch[] != NULL) x->ch[]->lazy += x->lazy;
- x->val+=x->lazy;
- }
- x->lazy = ;
- }
- void Update (node *x) {
- x->Csize();
- x->Csum();
- }
- void Rotate (node *x, int sta) { //单旋转操作,0左旋,1右旋
- node *p = x->pre, *g = p->pre;
- Push_Down (p), Push_Down (x);
- p->ch[!sta] = x->ch[sta];
- if (x->ch[sta] != NULL) x->ch[sta]->pre = p;
- x->pre = g;
- if (g != NIL)
- if (g->ch[] == p) g->ch[] = x;
- else g->ch[] = x;
- x->ch[sta] = p, p->pre = x, Update (p);
- if (p == root ) root = x;
- }
- void splay (node *x, node *y) { //Splay 操作,表示把结点x,转到根
- for (Push_Down (x) ; x->pre != y;) { //将x的标记往下传
- if (x->pre->pre == y) { //目标结点为父结点
- if (x->pre->ch[] == x) Rotate (x, );
- else Rotate (x, );
- }
- else {
- node *p = x->pre, *g = p->pre;
- if (g->ch[] == p)
- if (p->ch[] == x)
- Rotate (p, ), Rotate (x, );// / 一字型双旋转
- else
- Rotate (x, ), Rotate (x, );// < 之字形双旋转
- else if (p ->ch[] == x)
- Rotate (p, ), Rotate (x, );// \ 一字型旋转
- else
- Rotate (x, ), Rotate (x, ); // >之字形旋转
- }
- }
- Update (x); //维护x结点
- }
- //找到中序便利的第K个结点,并旋转至结点y的下面。
- void Select (int k, node *y) {
- int tem ;
- node *t ;
- for ( t = root; ; ) {
- Push_Down (t) ; //标记下传
- tem = t->ch[]->Size ;
- if (k == tem + ) break ; //找到了第k个结点 t
- if (k <= tem)
- t = t->ch[] ; //第k个结点在左子树
- else
- k -= tem + , t = t->ch[] ;//在右子树
- }
- splay (t, y);
- }
- bool Search (ll key, node *y) {
- node *t = root;
- for (; t != NULL;) {
- Push_Down (t);
- if (t->key > key && t->ch[] != NULL) t = t->ch[];
- else if (t->key < key && t->ch[] != NULL) t = t->ch[];
- else
- break;
- }
- splay (t, y);
- return t->key == key;
- }
- void Insert (int key, int val) {
- if (Search (key, NIL) ) root->Cnt++, root->Size++;
- else {
- int d = key > root->key;
- node *t = & (nod[++ncnt] = node (key) );
- Push_Down (root);
- t->val = t->sum = val;
- t->ch[d] = root->ch[d];
- if (root->ch[d] != NULL) root->ch[d]->pre = t;
- t->ch[!d] = root;
- t->pre = root->pre;
- root->pre = t;
- root->ch[d] = NULL;
- Update (root);
- root = t;
- }
- Update (root);
- }
- } sp;
- ll n, m, x;
- int main() {
- scanf ("%lld %lld", &n, &m);
- sp.Insert (, );
- sp.Insert (n + , );
- for (int i = ; i <= n; i++) {
- scanf ("%lld", &x);
- sp.Insert (i, x);
- }
- char cmd;
- int l, r;
- for (int i = ; i <= m; i++) {
- scanf ("\n%c %d %d", &cmd, &l, &r);
- sp.Search (l - , NIL);
- sp.Search (r + , sp.root);
- if (cmd == 'Q') {
- node *t = sp.root->ch[]->ch[];
- ll ans = t->sum + t->Size * t->lazy;
- printf ("%lld\n", ans);
- }
- if (cmd == 'C') {
- ll c;
- scanf ("%lld", &c);
- sp.root->ch[]->ch[]->lazy += c;
- }
- }
- return ;
- }
POJ 3468.A Simple Problem with Integers 解题报告的更多相关文章
- POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)
POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...
- poj 3468 A Simple Problem with Integers 【线段树-成段更新】
题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...
- 线段树(成段更新) POJ 3468 A Simple Problem with Integers
题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ...
- poj 3468 A Simple Problem with Integers(线段树+区间更新+区间求和)
题目链接:id=3468http://">http://poj.org/problem? id=3468 A Simple Problem with Integers Time Lim ...
- POJ 3468 A Simple Problem with Integers(分块入门)
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- POJ 3468 A Simple Problem with Integers(线段树功能:区间加减区间求和)
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- [ACM] poj 3468 A Simple Problem with Integers(段树,为段更新,懒惰的标志)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 55273 ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
随机推荐
- HDU -- 4496
D-City Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Subm ...
- loadrunner打不开ie&ie默认浏览器设置方法
loadrunner使用过程中频繁的出现问题,出现次数最多的就是lr打不开ie,或者ie一闪就关闭了,问题出在我默认浏览器的设置上,因为我原先并没有成功设置ie为默认浏览器.这是一个无意识的错误,我以 ...
- VS2010 快速写入注释小技巧
/************************************************************************//* *//******************* ...
- cocos2d的ARC开启
ARC,官方解释是Automatic Reference Counting,是Apple公司从iOS5开始为开发者新添加的一个功能. 相信很多写移动开发,可能不只是移动开发的人都深有体会,创建一个对象 ...
- [git] git 的基本认知
版本管理 ( Version Control ) 版本管理系统是一个记录文件变更的系统,让你在一段时间后可以恢复指定版本的文件.版本管理系统大致可分为三类:独立的本地版本管理系统.中心化版本管理系统. ...
- STL之set、multiset、functor&pair使用方法
set是一个集合容器,其中包含的元素是唯一的,集合中的元素是按照一定的顺序排列的.元素插入过程是按照排序规则插入,所以不能使用指定位置插入. set采用红黑树变体的数据结构实现,红黑树属于平衡二叉树. ...
- openStack 性能开测-2
- python处理xml的常用包(lib.xml、ElementTree、lxml)
python处理xml的三种常见机制 dom(随机访问机制) sax(Simple APIs for XML,事件驱动机制) etree python处理xml的三种包 标准库中的xml Fredri ...
- iOS开发总结-类似京东分类,UICollectionView
// // TypeViewController.m // BJ // // Created by shirenfeng on 16/11/6. // Copyright © 2016年 com.ws ...
- C:\WINDOWS\system32\drivers\etc\hosts host文件夹里面的内容是什么?
这个文件是根据TCP/IP for Windows 的标准来工作的,它的作用是包含IP地址和Host name(主机名)的映射关系,是一个映射IP地址和Host name(主机名)的规定,规定要求每段 ...