各种操作,区间更新,求最值、翻转、插入、删除、当然是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. 警告: 隐式声明与内建函数‘exit’不兼容 [默认启用]

    警告: 隐式声明与内建函数‘exit’不兼容 [默认启用] 最近在学习linux下的多任务编程,用到exit等函数时,经常出现该警告,查找资料后发现,原因其实很简单,没有把stdlib.h头文件包含进 ...

  2. Python进阶(面向对象编程基础)(一)

    鉴于昨天被类和函数折腾得晕头转向,今特把类的知识翻出来温习. 1.定义类并创建实力对象 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ ...

  3. Java中的线程Thread总结

    首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的! 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口. 要注意的是Threa ...

  4. MySQL 可以用localhost 连接,但不能用IP连接的问题,局域网192.168.*.* 无法连接mysql

    Mysql 默认是没有开启这个权限的(只允许使用 host:localhost,或者 host:127.0.0.1),如果想用 host:192.168.1.* ,来访问mysql ,需要手动开启这个 ...

  5. Solr的安装

    1.   JDK要求 Solr 4.10 要求JDK版本必须是1.7或更高. 下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/ 下载得到z ...

  6. jQuery下的显示和隐藏

    因为太久没更新了,所以来放一点没意思的内容. 做的是jQuery框架的隐藏和显示,HTML如下: <ul> <li>1</li> <li>2</l ...

  7. C#如何以管理员身份运行程序(转)

    在使用winform程序获取调用cmd命令提示符时,如果是win7以上的操作系统,会需要必须以管理员身份运行才会执行成功,否则无效果或提示错误. 比如在通过winform程序执行cmd命令时,某些情况 ...

  8. (转)检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(转)

    我们将ASP.NET程序从IIS6移植到IIS7,可能运行提示以下错误: HTTP 错误 500.23 - Internal Server Error 检测到在集成的托管管道模式下不适用的 ASP.N ...

  9. java下socket传图片

    package cn.stat.p4.ipdemo; import java.io.File; import java.io.FileOutputStream; import java.io.IOEx ...

  10. defer和async

    1.decument.wirte不能使用 2.<script src="text.js" type="text/javascript" defer=&qu ...