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 ...
随机推荐
- HDU 5245
题目大意: 每次随机选择两个点,便把这两个点之间形成的子矩阵上的每一个方块涂色,问随机选择k次,整个m*n的矩阵中有多少个小方块被涂上了颜色 这道题不难,但自己智商实在捉急,一直想不出来... 因为这 ...
- hdu1160简单dp最长下降子序列
/* 简单dp,要记录顺序 解:先排序,然后是一个最长下降子序列 ,中间需记录顺序 dp[i]=Max(dp[i],dp[j]+1); */ #include<stdio.h> #incl ...
- UltraEdit-14.10.0.1024版本语法着色配置
用了UltraEdit有段时间了,一直没做语法着色,当做普通文本编辑器使用,这也太委屈这个“神器”了. 今天就让它物尽其用吧.体验一把UltraEdit的语法高亮功能. 参考:http://www.1 ...
- 最长递增子序列 (LIS) Longest Increasing Subsequence
问题描述: 有一个长为n的数列a0, a1,..., an-1.请求出这个序列中最长的上升子序列.请求出这个序列中最长的上升子序列. 上升子序列:对于任意i<j都满足ai<aj的子序列. ...
- 从jmm模型漫谈到happens-befor原则
首先,代码都没有用ide敲,所以不要在意格式,能看懂就行jmm内存模型: jmm是什么? jmm说白了就是定义了jvm中线程和主内存之间的抽象关系的一种模型,也就是线程之间的共享变量存储在主内存,而每 ...
- 洛谷—— P3372 【模板】线段树 1
P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...
- springboot整合mybatis,freemarker
springboot 整合mybaits,,freemarker pom.xml文件 <?xml version="1.0" encoding="UTF-8&quo ...
- redux-saga 异步流
前言 React的作用View层次的前端框架,自然少不了很多中间件(Redux Middleware)做数据处理, 而redux-saga就是其中之一,目前这个中间件在网上的资料还是比较少,估计应用的 ...
- [Android]自己定义带删除输入框
在项目开发中,带删除button输入框也是人们经常常使用到的,该文章便介绍一下怎样创建一个带删除输入框.当中,须要解决的问题例如以下: a)创建自己定义editText类 b)在自己定义editTex ...
- 【Linux编程】进程终止和exit函数
内核要运行一个应用程序,唯一的途径是通过系统调用.exec函数.exec又会调用启动程序,启动程序(一般是汇编语言)以类似以下的方式调用main函数: void exit(main(argc, arg ...