洛谷P3721 单旋
什么毒瘤......
题意:模拟一棵单旋splay,求每次插入,splay最值,删除最值的操作次数。
解:乍一看感觉很神,又因为是LCT题单上的,然后就折磨了我好久,最后跑去看题解...
居然是手玩找规律题!我疯了。
是这样的,因为它只会单旋,而且只会splay最值,手玩一下就发现整个树的形态不变......就是把一个节点拿上去当根了,然后它的子节点代替它的位置。
插入,根据普通splay插入可知它一定接在前驱/后继的下面。找到深度大的那个就行了。
具体来说,用一棵值域线段树维护每个权值的深度。同时还要记录根,fa,son,树中节点数...
线段树要支持区间加,单点修改,查询第k大,区间求和,单点查询等功能。
大力分类讨论,注意一波细节,然后就A了...
#include <cstdio>
#include <algorithm> const int N = ; struct Node {
int f, x;
}node[N]; int tag[N * ], sum[N * ], fa[N], s[N][], X[N], temp; inline void pushdown(int o) {
if(tag[o]) {
tag[o << ] += tag[o];
tag[o << | ] += tag[o];
tag[o] = ;
}
return;
} int ask(int p, int l, int r, int o) {
if(l == r) {
if(!sum[o]) {
tag[o] = ;
}
return tag[o];
}
pushdown(o);
int mid = (l + r) >> ;
if(p <= mid) {
return ask(p, l, mid, o << );
}
else {
return ask(p, mid + , r, o << | );
}
} void change(int p, int v, int l, int r, int o) {
if(l == r) {
if(v == -) {
sum[o] = tag[o] = ;
}
else {
sum[o] = ;
tag[o] = v;
}
return;
}
pushdown(o);
int mid = (l + r) >> ;
if(p <= mid) {
change(p, v, l, mid, o << );
}
else {
change(p, v, mid + , r, o << | );
}
sum[o] = sum[o << ] + sum[o << | ];
return;
} int getK(int k, int l, int r, int o) {
if(l == r) {
return r;
}
int mid = (l + r) >> ;
if(k <= sum[o << ]) {
return getK(k, l, mid, o << );
}
else {
return getK(k - sum[o << ], mid + , r, o << | );
}
} int getSum(int L, int R, int l, int r, int o) {
if(L <= l && r <= R) {
return sum[o];
}
int mid = (l + r) >> , ans = ;
if(L <= mid) {
ans += getSum(L, R, l, mid, o << );
}
if(mid < R) {
ans += getSum(L, R, mid + , r, o << | );
}
return ans;
} void add(int L, int R, int v, int l, int r, int o) {
if(L <= l && r <= R) {
tag[o] += v;
return;
}
pushdown(o);
int mid = (l + r) >> ;
if(L <= mid) {
add(L, R, v, l, mid, o << );
}
if(mid < R) {
add(L, R, v, mid + , r, o << | );
}
return;
} int main() {
int q, f, x, siz = , rt;
scanf("%d", &q);
for(int i = ; i <= q; i++) {
scanf("%d", &node[i].f);
if(node[i].f == ) {
scanf("%d", &node[i].x);
X[++temp] = node[i].x;
}
}
std::sort(X + , X + temp + );
temp = std::unique(X + , X + temp + ) - X - ;
for(int i = ; i <= q; i++) {
f = node[i].f;
if(f == ) {
x = std::lower_bound(X + , X + temp + , node[i].x) - X;
int k = getSum(, x, , temp, ), d;
if(!siz) {
d = ;
rt = x;
}
else if(!k) {
int r = getK(, , temp, );
d = ask(r, , temp, ) + ;
fa[x] = r;
s[r][] = x;
}
else if(k == siz) {
int l = getK(siz, , temp, );
d = ask(l, , temp, ) + ;
fa[x] = l;
s[l][] = x;
}
else {
int l = getK(k, , temp, );
int r = getK(k + , , temp, );
int dl = ask(l, , temp, );
int dr = ask(r, , temp, );
if(dl > dr) {
d = dl + ;
fa[x] = l;
s[l][] = x;
}
else {
d = dr + ;
fa[x] = r;
s[r][] = x;
}
}
change(x, d, , temp, );
printf("%d\n", d);
siz++;
}
else if(f == ) { // splay small
x = getK(, , temp, );
int d = ask(x, , temp, );
if(d > ) {
int r = fa[x];
if(s[x][]) {
fa[s[x][]] = r;
}
s[r][] = s[x][];
add(r, temp, , , temp, );
change(x, , , temp, );
fa[x] = ;
s[x][] = rt;
fa[rt] = x;
rt = x;
}
printf("%d\n", d);
}
else if(f == ) {
x = getK(siz, , temp, );
int d = ask(x, , temp, );
if(d > ) {
int l = fa[x];
if(s[x][]) {
fa[s[x][]] = l;
}
s[l][] = s[x][];
add(, l, , , temp, );
change(x, , , temp, );
fa[x] = ;
s[x][] = rt;
fa[rt] = x;
rt = x;
}
printf("%d\n", d);
}
else if(f == ) {
x = getK(, , temp, );
int d = ask(x, , temp, );
if(d > ) {
int r = fa[x];
if(s[x][]) {
fa[s[x][]] = r;
}
s[r][] = s[x][];
add(, r - , -, , temp, );
}
else {
add(, temp, -, , temp, );
rt = s[x][];
fa[s[x][]] = ;
}
change(x, -, , temp, );
printf("%d\n", d);
siz--;
}
else if(f == ) {
x = getK(siz, , temp, );
int d = ask(x, , temp, );
if(d > ) {
int l = fa[x];
if(s[x][]) {
fa[s[x][]] = l;
}
s[l][] = s[x][];
add(l + , temp, -, , temp, );
}
else {
add(, temp, -, , temp, );
rt = s[x][];
fa[s[x][]] = ;
}
change(x, -, , temp, );
printf("%d\n", d);
siz--;
}
}
return ;
}
AC代码
洛谷P3721 单旋的更多相关文章
- 洛谷 P3721 - [AH2017/HNOI2017]单旋(LCT)
洛谷题面传送门 终于调出来这道题了,写篇题解( 首先碰到这样的题我们肯定要考虑每种操作会对树的形态产生怎样的影响: 插入操作:对于 BST 有一个性质是,当你插入一个节点时,其在 BST 上的父亲肯定 ...
- 洛谷P3721 [AH2017/HNOI2017]单旋(线段树 set spaly)
题意 题目链接 Sol 这题好毒瘤啊.. 首先要观察到几个性质: 将最小值旋转到根相当于把右子树变为祖先的左子树,然后将原来的根变为当前最小值 上述操作对深度的影响相当于右子树不变,其他的位置-1 然 ...
- 洛谷P3371单源最短路径SPFA算法
SPFA同样是一种基于贪心的算法,看过之前一篇blog的读者应该可以发现,SPFA和堆优化版的Dijkstra如此的相似,没错,但SPFA有一优点是Dijkstra没有的,就是它可以处理负边的情况. ...
- 洛谷P3371单源最短路径Dijkstra堆优化版及优先队列杂谈
其实堆优化版极其的简单,只要知道之前的Dijkstra怎么做,那么堆优化版就完全没有问题了. 在做之前,我们要先学会优先队列,来完成堆的任务,下面盘点了几种堆的表示方式. priority_queue ...
- 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)
首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...
- 洛谷 P4779 单源最短路径(标准版) 题解
题面 这道题就是标准的堆优化dijkstra: 注意堆优化的dijkstra在出队时判断vis,而不是在更新时判断vis #include <bits/stdc++.h> using na ...
- 洛谷3721 HNOI2017单旋(LCT+set+思维)
这题难道不是spaly裸题吗? 言归正传QWQ 一看到这个题目,其实第一反应是很懵X的 从来没有见过类似的题目啊,什么\(spaly\),单旋.QWQ很懵逼啊 不过,我们可以注意到这么一件事情,就是我 ...
- P3721 [AH2017/HNOI2017]单旋
题目:https://www.luogu.org/problemnew/show/P3721 手玩一下即可AC此题. 结论:插入x后,x要么会成为x的前驱的右儿子,要么成为x的后继的左儿子,这取决于它 ...
- 洛谷 P4779【模板】单源最短路径(标准版)
洛谷 P4779[模板]单源最短路径(标准版) 题目背景 2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路. 然后呢? 10 ...
随机推荐
- vb用createprocess启动其他应用程序
Option Explicit Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Lon ...
- 【php增删改查实例】第七节 - 部门管理模块(画一个datagrid表格)
在easyui中,datagrid组件需要用一个table标签去渲染. <table id="grid0" title="部门管理" class=&quo ...
- Wannafly挑战赛26-F-msc的棋盘[最小割转化dp]
题意 一个大小为 \(n*m\) 的棋盘,知道每一列放了多少棋子,求有多少摆放方案满足要求. \(n,m\leq 50\) . 分析 如果是求是否有方案的话可以考虑网络流,行列连边,列容量为 \(b_ ...
- SPIR-V*:面向 OpenCL™ 工作负载的英特尔® 显卡编译器默认接口
英特尔® 显卡编译器最近从 SPIR* 转换到 SPIR-V*,作为面向 OpenCL™ 工作负载的中间表示.这看起来像编译器的内部变化,对用户来说不可见,但是这展示了我们支持 Khronos* 开放 ...
- 现代OpenGL渲染管线介绍
原文摘选自 现代OpenGL渲染管线介绍 此文对最新的OpenGL做一个简单的介绍,如有理解错误,敬请指正.英文原文: https://glumpy.github.io/modern-gl.html ...
- nginx反向代理tomcat应用,struts2网站程序redirect时导致请求地址错误的解决方法
一个使用struts2的网站在登录页面需要进行redirect跳转,大致如下: <package name="admin" extends="httl-defaul ...
- Apache服务器出现Forbidden 403错误提示的解决方法总结
在配置Linux的 Apache服务时,经常会遇到http403错误,我今天配置测试时也出现了,最后解决了,总结了一下.http 403错误是拒绝访问的意思,有很多原因的.还有,这些问题在win平台的 ...
- PAT甲题题解-1078. Hashing (25)-hash散列
二次方探测解决冲突一开始理解错了,难怪一直WA.先寻找key%TSize的index处,如果冲突,那么依此寻找(key+j*j)%TSize的位置,j=1~TSize-1如果都没有空位,则输出'-' ...
- 20181204-4 互评Final版本
此次作业要求参见https://edu.cnblogs.com/campus/nenu/2018fall/homework/2478 互评 一.互评Final版本——杨老师粉丝群<PinBall ...
- JAVA 操作系统已经来到第五个版本了 现陆续放出三个版本 这是第二个版本
package System2; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import ...