POJ 3580:SuperMemo(Splay)
http://poj.org/problem?id=3580
题意:有6种操作,其中有两种之前没做过,就是Revolve操作和Min操作。Revolve一开始想着一个一个删一个一个插,觉得太暴力了,后来发现可以把要放到前面的一段切开,丢到前面去,就和上一题的Cut是一样的了。还有Min操作,一开始特别ZZ地想着只要找keytree的最左边就好了,然后发现并不是那样的,要维护一个 mi 值,一开始两个节点设成 INF,然后 pushup 的时候先把 val 赋给 mi,然后再和左右儿子对比。WA了好几次,找了下数据。。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iostream>
#include <stack>
#include <map>
#include <queue>
using namespace std;
#define N 1000100
#define INF 0x7fffffff
#define lson ch[x][0]
#define rson ch[x][1]
#define keytree ch[ch[root][1]][0] struct SplayTree
{
int num[N], rev[N], ch[N][], fa[N], val[N], sz[N], col[N], mi[N];
int n, root, cnt; void PushDown(int x)
{
if(rev[x]) {
swap(lson, rson);
if(lson) rev[lson] ^= ;
if(rson) rev[rson] ^= ;
rev[x] = ;
}
if(col[x]) {
if(lson) {
col[lson] += col[x];
val[lson] += col[x];
mi[lson] += col[x];
}
if(rson) {
col[rson] += col[x];
val[rson] += col[x];
mi[rson] += col[x];
}
col[x] = ;
}
} void PushUp(int x)
{
sz[x] = sz[lson] + sz[rson] + ;
mi[x] = val[x];
if(lson) mi[x] = min(mi[x], mi[lson]);
if(rson) mi[x] = min(mi[x], mi[rson]);
} int NewNode(int w, int f, int kind)
{
int x = ++cnt;
ch[x][] = ch[x][] = rev[x] = col[x] = ;
sz[x] = ; val[x] = w; fa[x] = f;
mi[x] = w;
ch[f][kind] = cnt;
return x;
} void Build(int l, int r, int &x, int f, int kind)
{
if(l > r) return ;
int m = (l + r) >> ;
x = NewNode(num[m], f, kind);
Build(l, m - , ch[x][], x, );
Build(m + , r, ch[x][], x, );
PushUp(x);
} void Init()
{
root = cnt = ;
rev[] = val[] = col[] = fa[] = sz[] = ch[][] = ch[][] = ;
mi[] = INF;
root = NewNode(INF, , );
ch[root][] = NewNode(INF, root, );
val[ch[root][]] = INF;
sz[root] = ;
Build(, n, keytree, ch[root][], );
PushUp(ch[root][]); PushUp(root);
} void Rotate(int x, int kind)
{
int y = fa[x], z = fa[y];
PushDown(y); PushDown(x);
ch[y][!kind] = ch[x][kind];
if(ch[y][!kind]) fa[ch[y][!kind]] = y;
if(z) {
if(y == ch[z][]) ch[z][] = x;
else ch[z][] = x;
}
fa[x] = z; fa[y] = x;
ch[x][kind] = y;
PushUp(y);
} void Splay(int x, int goal)
{
// printf("%d, %d\n", x, fa[x]);
PushDown(x);
while(fa[x] != goal) {
int y = fa[x], z = fa[y];
PushDown(z); PushDown(y); PushDown(x);
int kind1 = x == ch[y][];
int kind2 = y == ch[z][];
if(z == goal) {
Rotate(x, kind1);
} else {
if(kind1 == kind2) {
Rotate(y, kind1);
} else {
Rotate(x, kind1);
}
Rotate(x, kind2);
}
}
PushUp(x);
if(goal == ) root = x;
} void RTO(int k, int goal)
{
int x = root;
PushDown(x);
while(k != sz[lson] + ) {
if(k <= sz[lson]) x = lson;
else k -= sz[lson] + , x = rson;
PushDown(x);
}
// printf("%d, %d, %d\n", x, val[x], goal);
Splay(x, goal);
} void Add(int l, int r, int d)
{
RTO(l, ); RTO(r + , root);
col[keytree] += d;
val[keytree] += d;
mi[keytree] += d;
PushUp(ch[root][]); PushUp(root);
} void Reverse(int l, int r)
{
RTO(l, ); RTO(r + , root);
rev[keytree] ^= ;
PushUp(ch[root][]); PushUp(root);
} void Cut(int l, int r, int c)
{
RTO(l, ); RTO(r + , root);
PushUp(ch[root][]); PushUp(root);
// Debug();
// puts("---------");
int tmp = keytree;
keytree = ;
RTO(c, ); RTO(c + , root);
keytree = tmp;
fa[tmp] = ch[root][];
PushUp(ch[root][]); PushUp(root);
} void Revolve(int l, int r, int t)
{
t = (t % (r - l + ) + (r - l + )) % (r - l + );
if(t == ) return ;
Cut(r - t + , r, l);
// Debug();
PushUp(ch[root][]); PushUp(root);
} void Insert(int index, int w)
{
RTO(index + , ); RTO(index + , root);
keytree = NewNode(w, ch[root][], );
PushUp(ch[root][]); PushUp(root);
} void Delete(int index)
{
RTO(index, ); RTO(index + , root);
keytree = ;
PushUp(ch[root][]); PushUp(root);
} int Query(int l, int r)
{
RTO(l, );
RTO(r + , root);
// Debug();
return mi[keytree];
} void Travel(int x)
{
if(lson) Travel(lson);
printf("ttt : %d, %d, %d\n", x, val[x], mi[x]);
if(rson) Travel(rson);
} void Debug()
{
Travel(root);
}
}spy; int main()
{
int n;
while(~scanf("%d", &n)) {
spy.n = n;
for(int i = ; i <= n; i++) scanf("%d", &spy.num[i]);
spy.Init();
int m;
scanf("%d", &m);
while(m--) {
char s[];
int a, b, c;
scanf("%s", s);
if(s[] == 'A') {
scanf("%d%d%d", &a, &b, &c);
spy.Add(a, b, c);
} else if(s[] == 'M') {
scanf("%d%d", &a, &b);
printf("%d\n", spy.Query(a, b));
} else if(s[] == 'R' && s[] == 'E') {
scanf("%d%d", &a, &b);
spy.Reverse(a, b);
} else if(s[] == 'R' && s[] == 'O') {
scanf("%d%d%d", &a, &b, &c);
spy.Revolve(a, b, c);
} else if(s[] == 'I') {
scanf("%d%d", &a, &b);
spy.Insert(a, b);
} else if(s[] == 'D') {
scanf("%d", &a);
spy.Delete(a);
}
// spy.Debug();
}
}
return ;
} /*
5
1
2
3
4
5
2
REVOLVE 1 5 4
MIN 4 5 10
1 2 3 4 5 6 7 8 9 10
15
ADD 4 8 3
MIN 5 7
MIN 7 10
REVERSE 2 5
MIN 2 6
MIN 2 3
INSERT 3 4
MIN 3 4
MIN 5 10
DELETE 6
MIN 3 5
MIN 4 4
REVOLVE 3 6 7
MIN 5 8
MIN 7 10
**************************
8
9
2
7
4
2
3
4
7
9
*/
POJ 3580:SuperMemo(Splay)的更多相关文章
- POJ 1260:Pearls(DP)
http://poj.org/problem?id=1260 Pearls Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8 ...
- POJ 2192 :Zipper(DP)
http://poj.org/problem?id=2192 Zipper Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1 ...
- POJ 3104:Drying(二分)
题目大意:你有一台机器可以烘干衣物,现在有n个衣物需要烘干,每件衣服都有一个值表示含水量,烘干机一秒可以烘干k滴水,一件衣服不在烘干机上时会每秒自动蒸发一滴水,求最少用多少时间烘干所有衣服. 分析: ...
- POJ 1113:Wall(凸包)
http://poj.org/problem?id=1113 Wall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 346 ...
- POJ 3669 Meteor Shower(流星雨)
POJ 3669 Meteor Shower(流星雨) Time Limit: 1000MS Memory Limit: 65536K Description 题目描述 Bessie hears ...
- POJ 3253 Fence Repair (优先队列)
POJ 3253 Fence Repair (优先队列) Farmer John wants to repair a small length of the fence around the past ...
- P3391 【模板】文艺平衡树(Splay)新板子
P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转 ...
- fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)
题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...
- Windows Server 2012 虚拟化实战:存储(一)
在计算机世界我们随处可以见的一种方法,那就是抽象.1946年冯诺依曼提出了计算机的基本结构包含:计算器,存储器和I/O设备.这可能是对计算机这一新生事物最重要的一次抽象,它直接影响了今后几十年计算机软 ...
随机推荐
- MetInfo标签函数及参数
参数标签直接在页面中调用标签代码即可: 函数标签需要在页面PHP嵌入代码中通过参数定义转换方可使用,如$metlang=methtml_lang('-'),点击函数标签代码可查看函数标签详细使用方法: ...
- js获取页面及个元素高度、宽度
网页可见区域宽: document.body.clientWidth; 网页可见区域高: document.body.clientHeight; 网页可见区域宽: document.body.offs ...
- Xshell下VI打开文件中文乱码解决
修改 /etc/sysconfig/i18n 成如下值:LANG="zh_CN.utf8"LANGUAGE="zh_CN.utf8"SUPPORTED=&quo ...
- JS,CSS,HTML制作网页首页,视频轮播,隐藏点击等等。
在整个项目中,总共写了1000+的代码,可以更加简单优化的.整个主页交互效果能基本,包括轮播,视频,点击变化形状,移入蒙版,瀑布流加载滑动,旋转等等.轮播导航没有完全做完,暂时做了往右无限推动.个人觉 ...
- 树链剖分(单点更新,求区间最值,区间求和Bzoj1036)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 5759 Solved: 2383 [Submi ...
- windows系统调用 进程快照
#include "windows.h" #include "tlhelp32.h" #include "iostream" using n ...
- struts自定义拦截器
第01步:配置web.xml,启动struts框架 <?xml version="1.0" encoding="UTF-8"?> <web-a ...
- React-Native坑1:Invariant Violation:Application 项目名 has not been registered.
React-Native坑1:Invariant Violation:Application 项目名 has not been registered. 字数347 阅读1421 评论3 喜欢7 前言 ...
- po line received is canceled(恢复PO被取消的余量)
1張PO已部分收貨,後來由于某種原因,將部分收貨的PO明行取消,現在要對已收料的這一部分進行退貨處理,要怎麼做才好呢? [@more@]DATA COLLECTED===============COL ...
- 《Focus On 3D Terrain Programming》中一段代码的注释三
取自<Focus On 3D Terrain Programming>中的一段: //--------------------------------------------------- ...