题目: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优化的更多相关文章

  1. 【CF809D】Hitchhiking in the Baltic States(Splay,动态规划)

    [CF809D]Hitchhiking in the Baltic States(Splay,动态规划) 题面 CF 洛谷 题解 朴素\(dp\):设\(f[i][j]\)表示当前考虑到第\(i\)个 ...

  2. 【CF809D】Hitchhiking in the Baltic States Splay

    [CF809D]Hitchhiking in the Baltic States 题意:给你n个区间[li,ri],让你选出从中一个子序列,然后在子序列的每个区间里都选择一个tj,满足$t_1< ...

  3. CF809D Hitchhiking in the Baltic States

    CF809D Hitchhiking in the Baltic States CF809D 长度为n的序列{xi},n<=3e5,范围在(li,ri)之间,求LIS最长是多长g(i,l)表示前 ...

  4. CF 809D Hitchhiking in the Baltic States——splay+dp

    题目:http://codeforces.com/contest/809/problem/D 如果值是固定的,新加入一个值,可以让第一个值大于它的那个长度的值等于它. 如今值是一段区间,就对区间内的d ...

  5. 【CF809D】Hitchhiking in the Baltic States

    题意: 给你n个区间[li,ri],让你选出从中一个子序列,然后在子序列的每个区间里都选择一个tj,满足t1<t2<...<tlent1<t2<...<tlen.最 ...

  6. CF809D Hitchhiking in the Baltic States LIS、平衡树

    传送门 看到最长上升子序列肯定是DP 设\(f_i\)表示计算到当前,长度为\(i\)的最长上升子序列的最后一项的最小值,显然\(f_i\)是一个单调递增的序列. 转移:对于当前计算的元素\(x\), ...

  7. Codeforces 809D. Hitchhiking in the Baltic States

    Description 给出 \(n\) 个数 \(a_i\),每一个数有一个取值 \([l_i,r_i]\) ,你来确定每一个数,使得 \(LIS\) 最大 题面 Solution 按照平时做法,设 ...

  8. CodeForces 809D Hitchhiking in the Baltic States(FHQ-Treap)

    题意 给你长度为$n$的序列,序列中的每个元素$i$有一个区间限制$[l_i,r_i]$,你从中选出一个子序列,并给它们标号$x_i$,要求满足 $,∀i<j,x_i<x_j$,且$, ∀ ...

  9. E - Emptying the Baltic Kattis - emptyingbaltic (dijkstra堆优化)

    题目链接: E - Emptying the Baltic Kattis - emptyingbaltic 题目大意:n*m的地图, 每个格子有一个海拔高度, 当海拔<0的时候有水. 现在在(x ...

随机推荐

  1. P1979 [NOIP]华容道

    [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 B 玩的华 ...

  2. 51nod1184 第N个质数

    如题.$n \leq 1e9$. 方法零:二分,然后洲阁筛.要魔改一下的洲阁筛.跑得慢.卡卡能过.没意思. //#include<iostream> #include<cstring ...

  3. 时间戳转换成DateTime

    select DateAdd(hour,8,Dateadd(ss,时间戳,'1970-01-01'))   --1970/01/01+时间戳(秒数)+8小时 --因GMT是中央时区,北京在东8区,相差 ...

  4. T2627 村村通 codevs

    http://codevs.cn/problem/2627/  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题目描述 Description 农民约翰被选为他们 ...

  5. codeforces #302Div1 A

    对于 我这样的弱者就需要一道一道 简单的题 来慢慢补了. 看懂 题意很重要: 又一次被自己的英语吓哭了,做了两天发现题目看错,结果样例都对了, 硬是过不了: 给 n,m,b,mod; 在给n 个数 a ...

  6. [Bzoj2733][Hnoi2012] 永无乡(BST)(Pb_ds tree)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4108  Solved: 2195[Submit][Statu ...

  7. codeforces 938F(dp+高维前缀和)

    题意: 给一个长度为n的字符串,定义$k=\floor{log_2 n}$ 一共k轮操作,第i次操作要删除当前字符串恰好长度为$2^{i-1}$的子串 问最后剩余的字符串字典序最小是多少? 分析: 首 ...

  8. Wannafly模拟赛2 B river(拉格朗日乘数法)

    题目 https://www.nowcoder.com/acm/contest/4/B题意 有n条南北流向的河并列排着,水流速度是v,现在你需要从西岸游到东岸,总共T个时间,你的游泳速度是u,问东岸的 ...

  9. Org-mode五分钟教程ZZZ

    Table of Contents 1 源起 2 简介 2.1 获取 org-mode 2.2 安装 3 基础用法 3.1 创建一个新文件 3.2 简单的任务列表 3.3 使用标题组织一篇文章 3.4 ...

  10. javascript 自定义错误处理

    php 中是可以自定义程序的错误和异常处理函数的(handler).于是,我在想,javascript 中是否也存在和PHP中一样的异常和错误处理函数呢? try{}catch(){} 这种捕捉异常和 ...