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










*/

POJ 3580:SuperMemo(Splay)的更多相关文章

  1. POJ 1260:Pearls(DP)

    http://poj.org/problem?id=1260 Pearls Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8 ...

  2. POJ 2192 :Zipper(DP)

    http://poj.org/problem?id=2192 Zipper Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1 ...

  3. POJ 3104:Drying(二分)

    题目大意:你有一台机器可以烘干衣物,现在有n个衣物需要烘干,每件衣服都有一个值表示含水量,烘干机一秒可以烘干k滴水,一件衣服不在烘干机上时会每秒自动蒸发一滴水,求最少用多少时间烘干所有衣服. 分析: ...

  4. POJ 1113:Wall(凸包)

    http://poj.org/problem?id=1113 Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 346 ...

  5. POJ 3669 Meteor Shower(流星雨)

    POJ 3669 Meteor Shower(流星雨) Time Limit: 1000MS    Memory Limit: 65536K Description 题目描述 Bessie hears ...

  6. POJ 3253 Fence Repair (优先队列)

    POJ 3253 Fence Repair (优先队列) Farmer John wants to repair a small length of the fence around the past ...

  7. P3391 【模板】文艺平衡树(Splay)新板子

    P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转 ...

  8. fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)

    题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...

  9. Windows Server 2012 虚拟化实战:存储(一)

    在计算机世界我们随处可以见的一种方法,那就是抽象.1946年冯诺依曼提出了计算机的基本结构包含:计算器,存储器和I/O设备.这可能是对计算机这一新生事物最重要的一次抽象,它直接影响了今后几十年计算机软 ...

随机推荐

  1. 如何激活一个window/dialog && 不能直接对Dialog Box使用SetFocus

    问题,症状: 程序的主窗口CMainWnd创建了一个modal dialog,希望这个dialog能接收WM_KEYDOWN消息,但是需要点一下这个dialog窗口它才能接收到(我嫌麻烦),而且我发现 ...

  2. UIPageControl

    UIPageControl 1.    numberOfPages // 设置有多少页默认为0 // 2) 设置页数 [pageControl setNumberOfPages:kImageCount ...

  3. Collections的排序之一(Java)

    package home.collection.arr; import java.util.ArrayList; import java.util.Collections; import java.u ...

  4. display:flex 多栏多列布局

    转自:http://www.360doc.com/content/14/0811/01/2633_400926000.shtml display:flex 多栏多列布局浏览器支持情况:火狐直接支持w3 ...

  5. JQuery 回到顶部效果

    图片,CSS/HTML/JS代码都在,可以直接用了. CSS代码 <style type="text/css"> #gs_feedback_gotop { _displ ...

  6. Synchronized及其实现原理

    并发编程中synchronized一直是元老级角色,我们称之为重量级锁.主要用在三个地方: 1.修饰普通方法,锁是当前实例对象. 2.修饰类方法,锁是当前类的Class对象. 3.修饰代码块,锁是sy ...

  7. .NET C#: NameValueCollection

    NameValueCollection class is in System.Collection.Specialized assembly. Unlike with HashTable, NameV ...

  8. Android Studio更新升级方法(转)

    自从2013 Google I/O大会之后,笔者就将android ide开发工具从eclipse迁移到Android Studio了,android studio一直在更新完善,为了与时俱进,我们当 ...

  9. 手动写的第一个eChart代码

    手动写的第一个eChart代码 ,第一感觉,杂乱无章 <!doctype html> <html> <head> <meta charset="UT ...

  10. 夺命雷公狗—angularjs—13—post参数的接收发送

    我们强悍的angularjs为我们不仅仅提供了他的get接收方式,而且也有post的接收方式,我们现在做一个模拟接收后端传递过来的json的数据: <?php $arr = ['user'=&g ...