CF 809 D Hitchhiking in the Baltic States —— 思路+DP(LIS)+splay优化
题目:http://codeforces.com/contest/809/problem/D
看题解,抄标程...发现自己连 splay 都快不会写了...
首先,题目就是要得到一个 LIS;
但与一般不同的是,新加入的不是一个值,而是一个取值范围;
仍是设 f[i] 表示长度为 i 的 LIS 的结尾最靠前是哪个位置,而此时新出现一个区间 l~r;
如果 f[i] < l,那么可以接上一个 l 变成 f[i+1],也就是 f[i+1] = l;
如果 l <= f[i] <= r,也可以把这个 f[i] 通过选这个区间里的值而尽量提前,最多能提前到上一个 f[j] , l <= f[j] < f[i] <= r;
也就是此时,f[i] = f[j] + 1;
可以知道上一个位置 j 就是 i-1,也就是新增区间带来了这样的转移:f[i] = min( f[i] , f[i-1] + 1),而 f[i-1] + 1 <= f[i] , 所以 f[i] = f[i-1] + 1;
综上,新增加一个区间:
1.会使 l 左边第一个 f[i] < l 转移到 f[i+1] = l;
2.使区间内部的值都向前跳到上一个的后一个,即 f[i+1] = f[i] + 1 , l <= f[i] < f[i+1] <= r;
3.使右边第一个 f[i] > r 转移到 f[i-1] + 1;
可以发现,转移2可以看做是区间内的 f[] 都向右移动了一下,然后区间左边第一个移动到了左端点,右边第一个移到区间内,同时角标(答案)+1;
就可以用 splay 维护,每次找到值在 l~r 范围内的,+1,再删除……,加入……什么的...
然后就模仿了标程的写法...
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls c[x][0]
#define rs c[x][1]
using namespace std;
int const xn=3e5+;
int n,Q,v[xn],lzy[xn],fa[xn],c[xn][],rt,ans;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void pushdown(int x)
{
if(!lzy[x])return;
v[ls]+=lzy[x]; lzy[ls]+=lzy[x];
v[rs]+=lzy[x]; lzy[rs]+=lzy[x];
lzy[x]=;
}
void push(int x)
{
if(fa[x])push(fa[x]);
pushdown(x);
}
void rotate(int x)
{
int y=fa[x],z=fa[y],d=(c[y][]==x);
if(z)c[z][c[z][]==y]=x;
fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
c[y][d]=c[x][!d]; c[x][!d]=y;
}
void splay(int x,int f)
{
push(x);//!
while(fa[x]!=f)
{
int y=fa[x],z=fa[y];
if(z!=f)
{
if((c[y][]==x)^(c[z][]==y))rotate(x);
else rotate(y);
}
rotate(x);
}
if(!f)rt=x;
}
int low(int k)//<=k
{
int nw=rt,ret=;
while(nw)
{
pushdown(nw);//!!!
if(v[nw]<k)ret=nw,nw=c[nw][];
else nw=c[nw][];
}
return ret;
}
int nxt(int x)
{
splay(x,); int nw=c[x][];
while(c[nw][])nw=c[nw][];
return nw;
}
void insert(int &x,int k,int f)
{
if(!x){v[x=++n]=k; fa[x]=f; splay(x,); return;}
pushdown(x);//!!
insert(c[x][k>v[x]],k,x);
}
void del(int x)
{
splay(x,); int p=c[x][],q=c[x][];
while(c[p][])p=c[p][];
while(c[q][])q=c[q][];
splay(p,); splay(q,p);
c[q][]=; fa[x]=;
}
void solve(int l,int r)
{
int p=low(l),q=low(r),t=nxt(q);
if(p!=q)//!
{
splay(p,); splay(t,p);
v[c[t][]]++; lzy[c[t][]]++;
}
if(t!=)del(t),ans--;
insert(p,l,); ans++;
}
int main()
{
Q=rd();
v[++n]=(<<); v[++n]=-(<<); fa[]=; c[][]=; rt=;//
for(int i=,l,r;i<=Q;i++)l=rd(),r=rd(),solve(l,r);
printf("%d\n",ans);
return ;
}
CF 809 D Hitchhiking in the Baltic States —— 思路+DP(LIS)+splay优化的更多相关文章
- 【CF809D】Hitchhiking in the Baltic States(Splay,动态规划)
[CF809D]Hitchhiking in the Baltic States(Splay,动态规划) 题面 CF 洛谷 题解 朴素\(dp\):设\(f[i][j]\)表示当前考虑到第\(i\)个 ...
- 【CF809D】Hitchhiking in the Baltic States Splay
[CF809D]Hitchhiking in the Baltic States 题意:给你n个区间[li,ri],让你选出从中一个子序列,然后在子序列的每个区间里都选择一个tj,满足$t_1< ...
- CF809D Hitchhiking in the Baltic States
CF809D Hitchhiking in the Baltic States CF809D 长度为n的序列{xi},n<=3e5,范围在(li,ri)之间,求LIS最长是多长g(i,l)表示前 ...
- CF 809D Hitchhiking in the Baltic States——splay+dp
题目:http://codeforces.com/contest/809/problem/D 如果值是固定的,新加入一个值,可以让第一个值大于它的那个长度的值等于它. 如今值是一段区间,就对区间内的d ...
- 【CF809D】Hitchhiking in the Baltic States
题意: 给你n个区间[li,ri],让你选出从中一个子序列,然后在子序列的每个区间里都选择一个tj,满足t1<t2<...<tlent1<t2<...<tlen.最 ...
- CF809D Hitchhiking in the Baltic States LIS、平衡树
传送门 看到最长上升子序列肯定是DP 设\(f_i\)表示计算到当前,长度为\(i\)的最长上升子序列的最后一项的最小值,显然\(f_i\)是一个单调递增的序列. 转移:对于当前计算的元素\(x\), ...
- Codeforces 809D. Hitchhiking in the Baltic States
Description 给出 \(n\) 个数 \(a_i\),每一个数有一个取值 \([l_i,r_i]\) ,你来确定每一个数,使得 \(LIS\) 最大 题面 Solution 按照平时做法,设 ...
- CodeForces 809D Hitchhiking in the Baltic States(FHQ-Treap)
题意 给你长度为$n$的序列,序列中的每个元素$i$有一个区间限制$[l_i,r_i]$,你从中选出一个子序列,并给它们标号$x_i$,要求满足 $,∀i<j,x_i<x_j$,且$, ∀ ...
- E - Emptying the Baltic Kattis - emptyingbaltic (dijkstra堆优化)
题目链接: E - Emptying the Baltic Kattis - emptyingbaltic 题目大意:n*m的地图, 每个格子有一个海拔高度, 当海拔<0的时候有水. 现在在(x ...
随机推荐
- CentOS 中 YUM 安装桌面环境
CentOS 作为服务器的操作系统是很常见的,但是因为需要稳定而没有很时髦的更新,所以很少做为桌面环境.在服务器上通常不需要安装桌面环境,最小化地安装 CentOS(也就是 minimal CentO ...
- 外星联络(bzoj 2251)
Description 小 P 在看过电影<超时空接触>(Contact)之后被深深的打动,决心致力于寻找外星人的事业.于是,他每天晚上都爬在屋顶上试图用自己的收音机收听外星人发来的信息. ...
- UVA12345 (带修改的莫队)
UVA12345 Dynamic len Problem : 给一个序列,每次询问一个区间里面的数字种类数量,或者修改某一个位置的值. Solution : 第一关键字分块排序左端点,第二关键字分块排 ...
- iOS 混合变换旋转 CGAffineTransform
在ios 中, Core Graphics 提供了一系列的函数可以在一个变换的基础上做深层次的变换,如果做一个既要缩放又要旋转的变换,以下的方法比较实用. CGAffineTransformScale ...
- Java使用IText(VM模版)导出PDF
Java使用IText(VM模版)导出PDF: public String createPDF(ProjectManageBase projectManageBase) { Map map = new ...
- Linux--进程组、会话、守护进程(转)
http://www.cnblogs.com/forstudy/archive/2012/04/03/2427683.html 进程组 一个或多个进程的集合 进程组ID: 正整数 两个函数 getpg ...
- 通过k8s(Kubernetes)搭建jmeter的压测环境master-slave架构,实现弹性伸缩
在k8s上部署jmeter的mater和slave,根据压测需求动态增减master和slave节点数量,即可以完成压测任务,又可以是资源利用最大化 https://blog.kubernauts.i ...
- 纠结的链接——ln、ln -s、fs.symlink、require
纠结的链接--ln.ln -s.fs.symlink.require 提交 我的留言 加载中 已留言 inode 我们首先来看看 linux 系统里面的一个重要概念:inode. 我们知道,文件存储在 ...
- Windows——cmd findstr 字符串查找增强使用说明
在文件中寻找字符串. 复制代码代码如下: FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [ ...
- OSChinaclient源代码学习(2)--缓存的设计
一.缓存的作用 请求数据的时候,首先进行推断,能否够从缓存中获取数据,假设满足条件,则直接从缓存中获取数据.否则请求新的数据.这样比没有缓存的情况下.每次都要从server请求数据要快,并且.没有网的 ...