首先LIS有个$O(n^2)$的DP方法

  $f(i,j)$表示前i个数,最后一个数<=j的LIS

  如果$a_i!=0$则有

  如果$a_i=0$则有

  注意因为$f(i-1,j)\leq f(i-1,j-1)+1$,所以上面第二个转移是成立的。

  用treap维护这个有两种写法。

  ①支持区间max=,区间+1。

  ②只要是只要求单点查询或者最后输出答案的区间操作都是可以用差分的。

  这题显然两个条件都满足233

  每次对一个区间+1的时候,实际上就是区间后移一位,直接插入一个点即可,然后l所在位置+1,(r+1)所在位置-1,但是这题我们维护的是前缀max,所以每个点的信息其实是前面任意一个地方的差分值里最大的,所以我们不能-1,而是如果区间右端点右边还有+1的话,就删掉最近的一个。

  $a_i=0$时,区间为$[l,r]$,$a_i!=0$,区间看成是$a_i$这个点。

  好像写丑了跑得很慢

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define lt tree[x].ls
#define rt tree[x].rs
using namespace std;
const int maxn=;
struct poi{int ls, rs, sum, rnd, size, w;}tree[maxn];
int n, l, r, tott, root, tmp, mx, now, cnt;
int a[maxn];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void build(int &x, int delta)
{
tree[x=++tott].w=tree[x].sum=delta;
tree[x].rnd=rand()<<|rand();
tree[x].size=;
}
inline void up(int x)
{
tree[x].size=tree[lt].size+tree[rt].size+;
tree[x].sum=tree[lt].sum+tree[rt].sum+tree[x].w;
}
void split(int x, int &l, int &r, int k)
{
if(!k) l=, r=x;
else if(tree[x].size==k) l=x, r=;
else if(tree[lt].size>=k) r=x, split(lt, l, lt, k), up(x);
else l=x, split(rt, rt, r, k-tree[lt].size-), up(x);
}
void merge(int &x, int l, int r)
{
if(!l || !r) x=l+r;
else if(tree[l].rnd>tree[r].rnd) x=l, merge(rt, rt, r), up(x);
else x=r, merge(lt, l, lt), up(x);
}
void find(int x)
{
if(tree[lt].sum) return find(lt);
now+=tree[lt].size+;
if(tree[x].w) return;
if(tree[rt].sum) return find(rt);
}
void del(int &root, int rk)
{
int x, y, z;
split(root, x, y, rk); split(x, z, x, rk-);
merge(root, z, y);
}
inline void solve(int l, int r)
{
int x, y, z;
build(tmp, ); split(root, x, y, l-);
merge(x, x, tmp); merge(root, x, y);
split(root, x, y, r);
if(tree[y].sum) {now=; find(y); del(y, now);}
merge(root, x, y);
split(root, x, y, mx); merge(root, x, y);
}
int main()
{
read(n); read(l); read(r); tree[].rnd=(1ll<<)-; mx=r;
for(int i=;i<=n;i++) read(a[i]), mx=max(mx, a[i]);
for(int i=;i<=mx;i++) build(tmp, ), merge(root, root, tmp);
for(int i=;i<=n;i++)
if(a[i]) solve(a[i], a[i]); else solve(l, r);
int x, y; split(root, x, y, mx);
printf("%d\n", tree[x].sum);
}

CH暑假欢乐赛 SRM 07 天才麻将少女KPM(DP+treap)的更多相关文章

  1. 汕头市队赛 SRM 07 D 天才麻将少女kpm

    这道题放了很久还是回来补了 D 天才麻将少女KPM SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂.     KPM上周叒打了n场麻将,但她这次又没控分,而且 ...

  2. 【SRM-07 D】天才麻将少女KPM

    Description 天才麻将少女KPM立志要在日麻界闯出一番名堂.KPM上周叒打了n场麻将,但她这次又没控分,而且因为是全市参与的麻将大赛,所以她的名次范围是0..10^5.名次可能等于0是因为K ...

  3. ContestHunter暑假欢乐赛 SRM 01 - 儿童节常数赛 爆陵记

    最后15min过了两题...MDZZ 果然是不适合OI赛制啊...半场写完三题还自信满满的,还好有CZL报哪题错了嘿嘿嘿(这算不算犯规了(逃 悲惨的故事*1....如果没有CZL的话T1 10分 悲惨 ...

  4. ContestHunter暑假欢乐赛 SRM 15

    菜菜给题解,良心出题人!但我还是照常写SRM一句话题解吧... T1经典题正解好像是贪心...我比较蠢写了个DP,不过还跑的挺快的 f[i]=min( f[j-a[j]-1] )+1  { j+a[j ...

  5. ContestHunter暑假欢乐赛 SRM 04

    逃了一场SRM(躺 A题可以看成0点到1点,有p的几率从0到1,1-p几率不动,求0到1的期望步数.很显然概率是不降序列数/n!,然后列个方程E[0] = E[0] * (1 - p) + 1,解得E ...

  6. ContestHunter暑假欢乐赛 SRM 02

    惨不忍睹 3个小时都干了些什么... 日常按顺序从A题开始(难度居然又不是递增的 第一眼A题就觉得很简单...写到一半才发现woc那是个环.感觉一下子复杂了,按照链的方法扩展的话要特判很多东西... ...

  7. ContestHunter暑假欢乐赛 SRM 09(TJM大傻逼选手再创佳绩)

    T1 f[i]为前i页最少被撕几页,用二分转移就行了,答案为ans=min(f[i]+(n-i)); 不知道为什么写挂了嗯 二分的l初始应该是0 T2 数位DP f[i][1/0][1/0][1/0] ...

  8. ContestHunter暑假欢乐赛 SRM 08

    rating再次跳水www A题贴HR题解!HR智商流选手太强啦!CYC也好强%%%发现了len>10大概率是Y B题 dp+bit优化,据LLQ大爷说splay也可以优化,都好强啊.. C题跑 ...

  9. ContestHunter暑假欢乐赛 SRM 06

    T1二分check...为什么这么显然的我没看出来TAT,还在想倒着加入并查集check什么的,题写太多思维定势啦QAQ T2是NOIP题的弱化版...当时没看出来,写了个DP.可以看出这一位比上一位 ...

随机推荐

  1. AtCoder | ARC102 | 瞎讲报告

    目录 ARC102 前言 正文 传送链接~ ARC102 前言 实在是太菜了....写完第一题就弃疗..感觉T3好歹也是道可做题吧!!然后T2怎么又是进制拆分! 正文 A 题意 给你两个数字\(n,k ...

  2. swapon和swapoff命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/yexiangCSDN/article/details/83182259 swapon命令用于激活Linux系统中交换空间, ...

  3. 关于php的array_diff和array_diff_assoc的使用总结

    关于php的array_diff和array_diff_assoc的使用总结 2015-11-07 17:01 184人阅读 评论(0) 收藏 举报  分类: php学习感想(1)  版权声明:本文为 ...

  4. 如何使用g++编译调用dll的c++代码

    本文将有以下4个部分来讲如何使用g++编译调用dll的c++代码. 1.如何调用dll 2.动态链接和静态链接的区别 3.g++的编译参数以及如何编译调用dll的c++代码 4.总结 1.如何调用dl ...

  5. java实验三 敏捷开发与XP实践

    一.实验内容 (一)敏捷开发与XP 软件开发流程的目的是为了提高软件开发.运营.维护的效率,并提高软件的质量.用户满意度.可靠性和软件的可维护性. 光有各种流程的思想是不够的,我们还要有一系列的工具来 ...

  6. 20172319 《Java程序设计教程》 第9周学习总结

    20172319 2018.05.06-05.14 <Java程序设计教程>第9周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考 ...

  7. 1001.A+B Format (20)的感受

    这是提交到Github的object-oriented文件夹里面的代码:https://github.com/sonnypp/object-oriented/tree/master/1001. 一.解 ...

  8. Apollo配置名词-学习1

    文章:Apollo分布式配置中心部署以及使用 部署环境为DEV(开发环境).FAT(测试环境).UAT(预生产).PRO(生产)

  9. Beta阶段团队项目开发篇章3

    例会时间 2016.12.6晚 例会照片 个人工作 上阶段任务验收 中英文切换功能已经实现,调查结果分析已经完成,博客基本撰写完成,在征求其他组员意见后发布.任务基本完成. 任务分配 组员 任务内容 ...

  10. 项目复审-Bata阶段

    项目复审-Bata阶段 小组的名字和链接 优点 缺点 名次 别看了你没救了 https://www.cnblogs.com/liaoyujun233/p/9148781.html 基本功能都已经实现, ...