POJ3580---SuperMemo (Splay)
各种操作,区间更新,求最值、翻转、插入、删除、当然是Splay这种神器了。
主要是 revolve这个操作,其实也就是3个区间翻转放到一块,
比如 REVOLVE x y T,T %= (y-x+1); 其实就是 先把 x y区间翻转,然后把 x x + c - 1区间和 x+ c y区间分别翻转。
代码:
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const int maxn = 1e5+;
int siz[maxn],minv[maxn],rev[maxn],addv[maxn],key[maxn];
int ch[maxn][],a[maxn],pre[maxn],s[maxn];
int n,tot1,tot2,root;
void NewNode(int &r,int father,int k)
{
if (tot2)
r = s[tot2--];
else
r = ++tot1;
pre[r] = father;
key[r] = k;
siz[r] = ;
minv[r] = k;
ch[r][] = ch[r][] = ;
}
void update_Rev(int r)
{
if (!r)
return ;
swap(ch[r][],ch[r][]);
rev[r] ^= ;
}
void push_up(int r)
{
siz[r] = siz[ch[r][]] + siz[ch[r][]] + ;
minv[r] = min(key[r],min(minv[ch[r][]],minv[ch[r][]]));
}
void update_add(int r,int val)
{
if (!r)
return ;
key[r] += val;
addv[r] += val;
minv[r] += val;
}
void push_down(int r)
{
if (rev[r])
{
update_Rev(ch[r][]);
update_Rev(ch[r][]);
rev[r] = ;
}
if (addv[r])
{
update_add(ch[r][],addv[r]);
update_add(ch[r][],addv[r]);
addv[r] = ;
}
} void build(int &x,int l,int r,int father)
{
if (l > r)
return;
int mid = (l + r) >> ;
NewNode(x,father,a[mid]);
build(ch[x][],l,mid-,x);
build(ch[x][],mid+,r,x);
push_up(x);
}
void init()
{
tot1 = root = tot2 = ;
for (int i = ; i <= n; i++)
scanf ("%d",a+i);
minv[root] = inf;
NewNode(root,,-);
NewNode(ch[root][],root,-);
build(ch[ch[root][]][],,n,ch[root][]);
push_up(root);
push_up(ch[root][]);
}
void Rotate(int x,int kind)
{
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if (pre[y])
ch[pre[y]][ch[pre[y]][] == y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
void Splay(int r,int goal)
{
push_down(r);
while (pre[r] != goal)
{
if (pre[pre[r]] == goal)
{
push_down(pre[r]);
push_down(r);
Rotate(r,ch[pre[r]][] == r);
}
else
{
int y = pre[r];
push_down(pre[y]);
push_down(y);
push_down(r);
int kind = (ch[pre[y]][] == y);
if (ch[y][kind] == r)
{
Rotate(y,!kind);
Rotate(r,!kind);
}
else
{
Rotate(r,kind);
Rotate(r,!kind);
}
}
}
push_up(r);
if (goal == )
root = r;
}
int Get_kth(int r,int k)
{
push_down(r);
int t = siz[ch[r][]] + ;
if (t == k)
return r;
else if (t <= k)
return Get_kth(ch[r][],k-t);
else
return Get_kth(ch[r][],k);
}
void eraser(int r)
{
if (!r)
return;
s[++tot2] = r;
eraser(ch[r][]);
eraser(ch[r][]);
}
void Delete(int x)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,x+),root);
eraser(ch[ch[root][]][]);
pre[ch[ch[root][]][]] = ;
ch[ch[root][]][] = ;
push_up(ch[root][]);
push_up(root);
}
void Insert(int x,int val)
{
Splay(Get_kth(root,x+),);
Splay(Get_kth(root,x+),root);
NewNode(ch[ch[root][]][],ch[root][],val);
push_up(ch[root][]);
push_up(root);
}
void ADD(int u,int v,int val)
{
Splay(Get_kth(root,u),);
Splay(Get_kth(root,v+),root);
update_add(ch[ch[root][]][],val);
push_up(ch[root][]);
push_up(root);
}
int query(int ua,int ub)
{
Splay(Get_kth(root,ua),);
Splay(Get_kth(root,ub+),root);
return minv[ch[ch[root][]][]];
}
void Reverse (int u,int v)
{
Splay (Get_kth(root,u),);
Splay (Get_kth(root,v+),root);
update_Rev (ch[ch[root][]][]);
push_up (ch[root][]);
push_up (root);
}
void revolve(int u,int v,int c)
{
int len = (v - u + );
c %= len;
if (!c)
return;
Reverse(u,v);
Reverse(u,u+c-);
Reverse(u+c,v);
}
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
while (~scanf ("%d",&n))
{
init();
int m;
scanf ("%d",&m);
for (int i = ; i < m; i++)
{
char op[];
int u,v,c;
scanf ("%s",op);
if (strcmp(op,"ADD") == )
{
scanf ("%d%d%d",&u,&v,&c);
ADD(u,v,c);
}
if (strcmp(op,"REVERSE") == )
{
scanf ("%d%d",&u,&v);
Reverse(u,v);
}
if (strcmp(op,"REVOLVE") == )
{
scanf ("%d%d%d",&u,&v,&c);
revolve(u,v,c);
}
if (strcmp(op,"INSERT") == )
{
scanf ("%d%d",&u,&v);
Insert(u,v);
}
if (strcmp(op,"DELETE") == )
{
scanf ("%d",&u);
Delete(u);
}
if (strcmp(op,"MIN") == )
{
scanf ("%d%d",&u,&v);
printf("%d\n",query(u,v));
}
}
}
return ;
}
POJ3580---SuperMemo (Splay)的更多相关文章
- POJ 3580:SuperMemo(Splay)
http://poj.org/problem?id=3580 题意:有6种操作,其中有两种之前没做过,就是Revolve操作和Min操作.Revolve一开始想着一个一个删一个一个插,觉得太暴力了,后 ...
- 【BZOJ3506】排序机械臂(Splay)
[BZOJ3506]排序机械臂(Splay) 题面 神TMBZOJ没有题面,感谢SYC的题面 洛谷的题面也不错 题解 对于每次旋转的物体 显然可以预处理出来 现在只要模拟旋转操作就行了 至于在哪里放标 ...
- 【BZOJ1500】【NOI2005】维修数列(Splay)
[BZOJ1500][NOI2005]维修数列(Splay) 题面 不想再看见这种毒瘤题,自己去BZOJ看 题解 Splay良心模板题 真的很简单 我一言不发 #include<iostream ...
- 【BZOJ1862】[ZJOI2006]游戏排名系统 (Splay)
[BZOJ1862][ZJOI2006]游戏排名系统 (Splay) 题面 BZOJ 洛谷 题解 双倍经验题
- 【BZOJ1056】[HAOI2008]排名系统(Splay)
[BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...
- 【BZOJ2329】括号修复(Splay)
[BZOJ2329]括号修复(Splay) 题面 BZOJ 洛谷 题解 本来想着用线段树来写 但是有一个区间翻转 所以不能用线段树了,就只能用平衡树 然后直接\(Splay\)就好了 注意一下几个标记 ...
- P3391 【模板】文艺平衡树(Splay)新板子
P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转 ...
- fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)
题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...
- BZOJ 1251 序列终结者(Splay)
题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术 ...
- 【BZOJ】1251: 序列终结者(splay)
http://www.lydsy.com/JudgeOnline/problem.php?id=1251 不行..为什么写个splay老是犯逗,这次又是null的mx没有赋值-maxlongint.. ...
随机推荐
- MySQL获取系统性能和状态
#!/bin/ksh INTERVAL=5 PREFIX=$INTERVAL-sec-status touch /tmp/running RUNFILE=/tmp/running my -e 'sho ...
- 通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail
面试高频题:单链表的逆置操作/链表逆序相关文章 点击打开 void init_node(node *tail,char *init_array) 这样声明函数是不正确的,函数的原意是通过数组初始化链表 ...
- Java基础知识强化57:经典排序之希尔排序(ShellSort)
1. 希尔排序的原理: 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出 ...
- Nginx的10万并发内核参数优化
关于内核参数的优化: net.ipv4.tcp_max_tw_buckets = 6000timewait的数量,默认是180000.net.ipv4.ip_local_port_range = 10 ...
- 初学Pexpect
概述 Pexpect 是 Don Libes 的 Expect 语言的一个 Python 实现,是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的 Python 模块 ...
- Linux内核ROP学习
0x00 前言 1.SMEP(Supervisor Mode Execution Protection):一种减缓内核利用的cpu策略,禁止内核态到用户态内存页的代码执行(32位的addresses ...
- Droppable(放置)组件
.加载方式 //class 加载方式 <div id="dd" class="easyui-droppable" data-options="a ...
- 【nodejs学习】1.文件操作
1.小文件拷贝,使用nodejs内置模块 var fs = require('fs'); function copy(src, dst){ fs.writeFileSync(dst, fs.readF ...
- AngularJs练习Demo19 Resource
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...
- linux 虚机增加硬盘大小 转自
转自http://blog.csdn.net/tongyu2009/article/details/8525384 当我做到#unzip liunx_oracle时候,提示disk full? [ ...