【Splay】 HDU 1754 I Hate It
2015-08-31 20:37
393 查看
点击打开链接
区间最值模板
需要在两端设置两个结点( 查询 [ l, r ] 时需 将 l-1 转到根结点,r+1转到l-1的儿子结点 这时 r+1的左儿子就是答案
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include <deque>
#include <set>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
typedef long long LL;
const int INF = 1<<29;
const LL mod = 1e9+7;
const int MAXN = 200050;
struct SPLAY
{
int pre[MAXN],key[MAXN],ch[MAXN][2],mx[MAXN],root,tol;
void init()
{
root=0,tol=0;
ch[root][0]=ch[root][1]=0;
}
void NewNode(int &r,int father,int k)
{
r= ++tol;
pre[r]=father;
key[r]=mx[r]=k;
ch[r][0]=ch[r][1]=0;
}
void pushup(int w)
{
mx[w]=max(max(mx[ch[w][0]],mx[ch[w][1]]),key[w]);
}
void Rotate(int x,int kind)//0为左旋,1为右旋
{
int y=pre[x];
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
pushup(y);
pushup(x);
}
//Splay调整,将r节点调整为goal的儿子
void Splay(int r,int goal)
{
while(pre[r]!=goal)
{
if(pre[pre[r]]==goal)
Rotate(r,ch[pre[r]][0]==r);
else
{
int y=pre[r];
int kind=ch[pre[y]][0]==y;
if(ch[y][kind]==r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
if(goal==0) root=r;
}
int query(int l,int r)
{
r+=2;
Splay(l,0);
Splay(r,l);
return mx[ch[r][0]];
}
void update(int x,int k)
{
x++;
Splay(x,0);
key[x]=k;
pushup(x);
}
void gao(int n,int m)
{
int a,b;
NewNode(root,0,INF);
for(int i=2;i<=n+1;i++)
{
scanf("%d",&a);
NewNode(b,i-1,a);
ch[i-1][1]=i;
}
NewNode(a,n+1,-INF);
ch[n+1][1]=n+2;
// for(int i=1;i<=n+2;i++)
// printf("%d :%d %d\n",i,ch[i][0],ch[i][1]);
for(int i=n+2;i>=1;i--)
pushup(i);
char s[4];
while(m--)
{
scanf("%s%d%d",s,&a,&b);
if(s[0]=='Q')
printf("%d\n",query(a,b));
else
update(a,b);
}
}
}s;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
s.init();
s.gao(n,m);
}
return 0;
}
区间最值模板
需要在两端设置两个结点( 查询 [ l, r ] 时需 将 l-1 转到根结点,r+1转到l-1的儿子结点 这时 r+1的左儿子就是答案
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include <deque>
#include <set>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
typedef long long LL;
const int INF = 1<<29;
const LL mod = 1e9+7;
const int MAXN = 200050;
struct SPLAY
{
int pre[MAXN],key[MAXN],ch[MAXN][2],mx[MAXN],root,tol;
void init()
{
root=0,tol=0;
ch[root][0]=ch[root][1]=0;
}
void NewNode(int &r,int father,int k)
{
r= ++tol;
pre[r]=father;
key[r]=mx[r]=k;
ch[r][0]=ch[r][1]=0;
}
void pushup(int w)
{
mx[w]=max(max(mx[ch[w][0]],mx[ch[w][1]]),key[w]);
}
void Rotate(int x,int kind)//0为左旋,1为右旋
{
int y=pre[x];
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
pushup(y);
pushup(x);
}
//Splay调整,将r节点调整为goal的儿子
void Splay(int r,int goal)
{
while(pre[r]!=goal)
{
if(pre[pre[r]]==goal)
Rotate(r,ch[pre[r]][0]==r);
else
{
int y=pre[r];
int kind=ch[pre[y]][0]==y;
if(ch[y][kind]==r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
if(goal==0) root=r;
}
int query(int l,int r)
{
r+=2;
Splay(l,0);
Splay(r,l);
return mx[ch[r][0]];
}
void update(int x,int k)
{
x++;
Splay(x,0);
key[x]=k;
pushup(x);
}
void gao(int n,int m)
{
int a,b;
NewNode(root,0,INF);
for(int i=2;i<=n+1;i++)
{
scanf("%d",&a);
NewNode(b,i-1,a);
ch[i-1][1]=i;
}
NewNode(a,n+1,-INF);
ch[n+1][1]=n+2;
// for(int i=1;i<=n+2;i++)
// printf("%d :%d %d\n",i,ch[i][0],ch[i][1]);
for(int i=n+2;i>=1;i--)
pushup(i);
char s[4];
while(m--)
{
scanf("%s%d%d",s,&a,&b);
if(s[0]=='Q')
printf("%d\n",query(a,b));
else
update(a,b);
}
}
}s;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
s.init();
s.gao(n,m);
}
return 0;
}
相关文章推荐
- LVM2详解
- 高精度计算:最大公约数【两个数字字符串】
- MySQL基本操作(三):字符集
- HDU 3008 Warcraft,动态规划,滚动数组
- 运算符/printf/scanf/if
- 设计堆栈类
- 优先队列
- Vysor 情怀玩法 (番外篇)--调戏妹子
- 语言学习目标
- JAVA中转义字符
- (4.2.16.4) ActivityManager
- js动态的在页面上增加或删除一个文本框
- 对于内存的一点笔记
- 二手车好大风,老平台都推新服务
- UNIX环境高级编程(7):文件和目录(1)
- CopyOnWriteArrayList与Collections.synchronizedList的性能对比
- 《剑指Offer》面试题:数值的整数次方
- scala实现设计模式之解释器模式
- Codeforces Round #250 (Div. 2) 437C The Child and Toy(脑洞贪心)
- 动态增加文本框