CF809D Hitchhiking in the Baltic States_a6t2007的博客-程序员宝宝

技术标签: 数据结构与算法  

题目描述:

luogu

题解:

平衡树模拟dp?

设$dp[i]$表示当前状态下长为$i$的合法子序列最后一位的最小值。

容易发现$dp[i]<dp[i+1]$。

然后就可以$dp$了。

(当前可操作区间为$[l,r]$)

1.$dp[i-1]<l$,有$dp[i]=min(dp[i],l)$。

此时满足$dp[i-1]<l \le dp[i]$。

2.$l \le dp[i-1] < r$,有$dp[i]=min(dp[i],dp[i-1]+1)$,

其实右边一定最右,因为$dp[i-1]<dp[i]$。

3.$dp[i-1] \ge r$,此时$dp[i]=dp[i]$。

我们可以用平衡树维护这个转移。

对于转移1,我们要插入一个$l$。

对于转移2,我们要将一段区间平移后+1。

所以,用splay维护插入、区间加法和删除。

注意三者顺序。

(splay双旋写成反双旋卡在第80个点卡了半天

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int inf = 0x7f7f7f7f;
const int N = 500050;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<'0'||ch>'9'){
     if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    x = f*c;
}
int n;
struct Splay
{
    int tot,rt,ch[N][2],fa[N],siz[N];
    int w[N],tag[N];
    Splay()
    {
        tot = 2;rt = 1;
        w[1] = -inf,w[2] = inf;
        fa[2] = 1,ch[1][1] = 2;
        siz[1] = 2,siz[2] = 1;
    }
    void update(int u){siz[u]=siz[ch[u][0]]+siz[ch[u][1]]+1;}
    void add(int u,int k){
     if(u)w[u]+=k,tag[u]+=k;}
    void pushdown(int u)
    {
        if(tag[u])
        {
            add(ch[u][0],tag[u]);
            add(ch[u][1],tag[u]);
            tag[u]=0;
        }
    }
    int now;
    void rotate(int x)
    {
        int y = fa[x],z = fa[y],k = (ch[y][1]==x);
        ch[z][ch[z][1]==y]=x,fa[x]=z;
        ch[y][k]=ch[x][!k],fa[ch[x][!k]]=y;
        ch[x][!k]=y,fa[y]=x;
        update(y),update(x);
    }
    int sta[N],tl;
    void down(int x)
    {
        sta[tl=1]=x;
        while(fa[x])x=fa[x],sta[++tl]=x;
        while(tl)pushdown(sta[tl--]);
    }
    void splay(int x,int goal)
    {
        down(x);
        while(fa[x]!=goal)
        {
            int y = fa[x],z = fa[y];
            if(z!=goal)
                (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
            rotate(x);
        }
        if(!goal)rt=x;
    }
    void get_qq(int u,int k)
    {
        if(!u)return ;pushdown(u);
        if(w[u]<=k)now=u,get_qq(ch[u][1],k);
        else get_qq(ch[u][0],k);
    }
    void get_hj(int u,int k)
    {
        if(!u)return ;pushdown(u);
        if(w[u]>=k)now=u,get_hj(ch[u][0],k);
        else get_hj(ch[u][1],k);
    }
    int qq(int k){get_qq(rt,k);splay(now,0);return now;}
    int hj(int k){get_hj(rt,k);splay(now,0);return now;}
    void work(int l,int r)
    {
        int lp,rp,u;
        
        lp = hj(r);
        if(lp!=2)
        {
            rp = hj(w[lp]+1),lp = qq(w[lp]-1);
            splay(lp,0),splay(rp,lp);
            ch[rp][0]=0;
            update(rp),update(lp);
        }

//        u = qq(inf-1);
//        splay(u,0);

        lp = qq(l-1),rp = hj(r);
        splay(lp,0),splay(rp,lp);
        add(ch[rp][0],1);

//        u = qq(inf-1);
//        splay(u,0);

        rp = hj(w[lp]+1);
        splay(lp,0),splay(rp,lp);
        u = ++tot;w[u]=l;
        siz[u] = 1,fa[u] = rp,ch[rp][0] = u;
        update(rp),update(lp);
//        splay(u,0);
        
//        int mid = (2int*l+3int*r)/5;
        u = qq(inf-1);
        splay(u,0);
    }
}tr;
int main()
{
//    freopen("tt.in","r",stdin);
    read(n);
    for(int l,r,i=1;i<=n;i++)
    {
        read(l),read(r);
        tr.work(l,r);
    }
    printf("%d\n",tr.siz[tr.rt]-2);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/LiGuanlin1124/p/11112685.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a6t2007/article/details/102106658

智能推荐

HashMap一看就会 put/get方法详解_hashmap的get和put方法_液!的博客-程序员宝宝

Hash冲突key使用hash函数进行hash运算得到的hash值再与n-1进行与操作,能保证全部落在数组对应的下标处n-1 末尾全是1 进行与运算范围在0~n-1之间所以Table数组长度一定要是2的n次方PUT方法进行hash运算得到数组中的下标如果没有碰撞,当前下标元素为null,则插入一个新的节点if ((p = tab[i = (n - 1) &amp; hash]...

用龙芯1c库实现无源蜂鸣器唱歌《送别》_送别的程序代码_勤为本的博客-程序员宝宝

用龙芯1c库在龙芯1c上用裸机编程实现无源蜂鸣器唱《送别》

installshield动态创建快捷方式_mejy的博客-程序员宝宝

帮助文档里的函数/*-----------------------------------------------------------*/ * * InstallShield Example Script * * Demonstrates the AddFolderIcon function. * * This example places a shortcut to an executabl

String index out of range: 1_ChangYan.的博客-程序员宝宝

String index out of range: 1遇到这类报错问题一般是字符串的索引越界。可以看看我报错的位置如图我是要对lessons字符串的每个字符获取后判断它是否等于’*’,结果一大意写成了lesson,少了一个"s",可以看到我上边已经把lesson定义为"空",自然是获取不到的,所以就报出了上边的错误,还是要细心啊!...

uni-app引入小程序自定义组件_zeroyulong的博客-程序员宝宝

参见官方文档https://uniapp.dcloud.io/frame?id=%e5%b0%8f%e7%a8%8b%e5%ba%8f%e7%bb%84%e4%bb%b6%e6%94%af%e6%8c%811.新建wxcomponents文件夹,存放组件 ┌─wxcomponents 微信小程序自定义组件存放目录│ └──custom 微信小程序自定义组件│ ├─index.js│

DOM03-程序员宝宝

DOM03DOM03复习双标签内容计数器计数器升级计数器委托小计数组转HTML练习练习 - 升级练习练习 - 将数据显示在表格中购物车 - 1.7pm 108分DOM03复习DOM: Document Object Model 文档对象模型HTML文本代码 -&gt; 转化成DOM -&gt; 显示在浏览器上浏览器展示的是DOM, 通过操作DOM 就可以实时修改浏览器的效果查找元素:固定元素读取document.headdocument.bodydocument.documentEl

随便推点

static code analysis_青峰祭坛的博客-程序员宝宝

static code analysishttp://docs.oclint.org/en/dev/intro/tutorial.html (oclint) for objective-cFrom Wikipedia, the free encyclopediaJump to: navigation, searchThis is a list o

求整数均值 (10分)_黄大仙No.1的博客-程序员宝宝

本题要求编写程序,计算4个整数的和与平均值。题目保证输入与输出均在整型范围内。输入格式:输入在一行中给出4个整数,其间以空格分隔。输出格式:在一行中按照格式“Sum = 和; Average = 平均值”顺序输出和与平均值,其中平均值精确到小数点后一位。输入样例:1 2 3 4输出样例:Sum = 10; Average = 2.5#include&lt;stdio.h&gt;int main(void){ int m,n,sum=0; for(n=1;n&lt;=4;n++){

U3D游戏开发效率和UE4相比哪个高?_u3d和ue4学哪个好_xzljj的博客-程序员宝宝

很多人都在问,U3D游戏开发效率和UE4相比哪个高?今天就来跟大家分享一下!一般从0开始的游戏开发U3D的开发效率比UE4高。技术角度:对RPG 来说,两个引擎的基础系统支撑现成可用的东西不多(大概UE的CharacterMovement多少有点用)。对卡通渲染来说,U3D的实现难度和灵活性要显著优于UE4。广义一点说,单看渲染层的扩展性,答案也一样。对一般游戏开发来说大概七成以上的代码量会在逻辑和工具层,而这一层的代码,C#无论从语法糖还是编译调试效率,优势都很明显。U3D的编辑器

带你深入理解isNaN()函数(关于isNaN()出现的问题)_isnan函数什么意思_一个爱编程的男孩的博客-程序员宝宝

iSNaN()的官方描述是:isNaN() 函数可用于判断其参数是否是 NaN,该值表示一个非法的数字(比如被 0 除后得到的结果)。如果把 NaN 与任何值(包括其自身)相比得到的结果均是 false,所以要判断某个值是否是 NaN,不能使用 == 或 === 运算符。正因为如此,isNaN() 函数是必需的。isNaN() 函数其实并不能像它的描述中所写的那样,数字值返回 false,其他返回 true。实际上,它是判断一个值能否被 Number() 合法地转化成数字。这中间有什么区别呢,主要提

KMP例题_小白小郑的博客-程序员宝宝

前言笔者初学KMP算法,对KMP还不能做到分析全面,网上有很多写KMP算法的优质文章。本文就不讲解KMP算法,仅写KMP算法如何运用在题目中。推荐学习KMP链接题目例一:Youhane Assembler 牛客题目链接题意:输入多个字符串,挑选两个字符串s1,s2。判断s1的后缀字母与s2的前缀字母有多少个字符能匹配。eg:s1=“ABCDE” s2=“CDEFG”ps:它们能匹配的字符有3个为"CDE"。eg: s1=“CDEFG” s2=“ABCDE”ps:它们能匹配的字符有0个

xadmin常用样式功能_宅神kin的博客-程序员宝宝

文章目录model_icon 菜单图标style_fieldslist_displaysearch_fieldslist_filterdate_hierarchyorderingfieldsfilter_horizontalraw_id_fieldslist_editablereadonly_fieldsexcluderefresh_timesshow_detail_fieldsrelfield_...

推荐文章

热门文章

相关标签