各种操作,区间更新,求最值、翻转、插入、删除、当然是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)的更多相关文章

  1. POJ 3580:SuperMemo(Splay)

    http://poj.org/problem?id=3580 题意:有6种操作,其中有两种之前没做过,就是Revolve操作和Min操作.Revolve一开始想着一个一个删一个一个插,觉得太暴力了,后 ...

  2. 【BZOJ3506】排序机械臂(Splay)

    [BZOJ3506]排序机械臂(Splay) 题面 神TMBZOJ没有题面,感谢SYC的题面 洛谷的题面也不错 题解 对于每次旋转的物体 显然可以预处理出来 现在只要模拟旋转操作就行了 至于在哪里放标 ...

  3. 【BZOJ1500】【NOI2005】维修数列(Splay)

    [BZOJ1500][NOI2005]维修数列(Splay) 题面 不想再看见这种毒瘤题,自己去BZOJ看 题解 Splay良心模板题 真的很简单 我一言不发 #include<iostream ...

  4. 【BZOJ1862】[ZJOI2006]游戏排名系统 (Splay)

    [BZOJ1862][ZJOI2006]游戏排名系统 (Splay) 题面 BZOJ 洛谷 题解 双倍经验题

  5. 【BZOJ1056】[HAOI2008]排名系统(Splay)

    [BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...

  6. 【BZOJ2329】括号修复(Splay)

    [BZOJ2329]括号修复(Splay) 题面 BZOJ 洛谷 题解 本来想着用线段树来写 但是有一个区间翻转 所以不能用线段树了,就只能用平衡树 然后直接\(Splay\)就好了 注意一下几个标记 ...

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

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

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

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

  9. BZOJ 1251 序列终结者(Splay)

    题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术 ...

  10. 【BZOJ】1251: 序列终结者(splay)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1251 不行..为什么写个splay老是犯逗,这次又是null的mx没有赋值-maxlongint.. ...

随机推荐

  1. adjtimex使用

    adjtimex使用 今天遇到一个ntp的同步问题.服务器上配置好了ntpd,在启动前也手动进行过同步,但是过段时间ntpq查询发现服务器即便能选出同步服务器,但是系统的时间偏差越来越大. 服务器上实 ...

  2. i&1、负数二进制

    if(i&1==1) 表示 如果是 奇数 则...i&1 -- 按位与运算,取 2进制整数 i 的最低位,如果最低位是1 则得1,如果最低位是0 则得0. 奇数 i 的最低位 是1,偶 ...

  3. C++编程规范之19:总是初始化变量

    摘要: 一切从白纸开始,未初始化的变量是C和C++程序中错误的常见来源.养成在使用内存之前先清除的习惯,可以避免这种错误,在定义变量的时候就将其初始化. 按照C和C++相同的低层高效率传统,通常并不要 ...

  4. 最好的Laravel中文文档

    分页 配置 基本用法 给分页链接添加自定义信息 配置 在其它的框架中,分页有时很痛苦. 但是Laravel让分页简单到不可思议. 默认Laravel包含了两个分页视图, 在app/config/vie ...

  5. java byte 16进制转换

    整型转16进制: int devIdInt = Integer.parseInt(devId);String devIdString = Integer.toHexString(devIdInt); ...

  6. 挂载(mount)深入理解

    首先引用一句 wiki 上的定义来开篇: Mounting takes place before a computer can use any kind of storage device (such ...

  7. 内部类之.this&&.new

    一..this 我们都知道this是指当前类中的对象本身,但是在内部类中需要指明外部类时,this不再起作用,那应该怎么做呢?下面,让我们看看: public class DotThis { void ...

  8. response和request

    请求响应流程图 response response是用来向客户端响应的对象! 需要回忆一下http响应内容: l  首行:状态码 l  响应头: 1头1值,1头多值: l  响应体(正文):html ...

  9. 配置squid代理服务

    1. 简述一下squid的用途?squid可以做代理和缓存服务器,而做代理时,可以分为正向代理和反向代理.正向代理用在企业办公环境中,企业员工上网通过代理来上网,代理的缓存功能可以为企业节省宝贵的带宽 ...

  10. Calendar( 日历)

    本节课重点了解 EasyUI 中 Canlendar(日历)组件的使用方法,这个组件不依赖于其他组件.一. 加载方式//class 加载方式<div id="box" cla ...