这道题放了很久还是回来补了

D 天才麻将少女KPM SRM 07

背景&&描述

天才麻将少女KPM立志要在日麻界闯出一番名堂。
    KPM上周叒打了n场麻将,但她这次又没控分,而且因为是全市参与的麻将大赛,所以她的名次范围是0..10^5。
    名次可能等于0是因为KPM那场没去打= =
    没去打就意味着无限的可能性。
    KPM叒想要让自己的名次严格递增。为了避免被妹子怀疑,她只能把没打的比赛的名次改成T..R中的整数
    当然,n场全部严格递增是很难做到的。你只需要求出可能的最长递增子序列长度就好了。

输入格式

第一行三个整数n,T,R。
第二行n个整数,表示n场的排名。

输出格式

可能的最长递增子序列长度。

样例输入

5 1 4
3 0 5 9 2

样例输出

4

数据范围与约定

  • 对于100%的数据:

先贴一波大爷的题解

做严格上升 f【i】表示当前以i结尾的最大答案

a【j】!=0照常 a【j】==0的话就有f【i】=max(f【i】,f【i-1】)+1;(L<=i<=R)

f【i-1】一定>=f【i】所以相当于+1后整体平移一格 用平衡树就可以实现了

所以实际涉及到的操作有区间更新 单点插入和删除

————————————————————————————————————

接下来自然就是我自己的写法咯‘

f【w】表示考虑到当前点的以w结尾的最长上升字序列的长度

其实f数组可以写成f【x】【i】 表示到第x个数以i结尾的最长上升子序列

但是明显我们用到的只有上一个点的信息 所以完全可以压成一维

实际上开成两维空间也接受不了

但是啊 因为我懒得弄区间操作所以我写成了差分 即树上维护的是f【i】-f【i-1】

这样转换之后就只涉及到单点插入修改

在涉及到的区间左端点位置插入一个值 删除右端点右侧的第一个1

至于为什么请听我细细道来...
首先我们考虑f【i-1】+1和f【i】的关系

0<=f【i】-f【i-1】<=1 这个很好证明吧

f【i】是一定>f【i-1】的 如果f【i】-f【i-1】大于1 那么序列不可能严格递增

所以相当于直接将区间+1后挪动一个位置 将取max直接改为赋值

因为我维护的是差分 就相当于在左端点处插入一个点,删去右端点后面的第一个1

至于左右端点 如果a【i】是0 自然是 l——r 否则就是那一个点咯(一个点也是区间)

至于为什么要删除 因为他能够影响到的就只能到右端点后第一个1 这个自己画图模拟一下咯

所以我们平衡树需要维护的就是区间是否有1 以及子树size

splay删除实在太恶心 所以我写了fhq treap

单点插入容易 分裂合并一波就好了

删除右端点后的第一个点就需要用到我们维护的——区间内是否有1

先把右端点后的区间分裂出来 考虑当前点x

if x的左子树有1 那么就往左子树跑

else if x本身有1 就删除x

else 往右子树跑

至于怎么删除x 把他的左右子树合在一起(merge)就好了

最后的答案就统计一下到0——a【i】的最大值之间有多少个1就行了

可能讲完这些还不是很清楚 不然来模拟一波样例吧

5 1 4
3 0 5 9 2

f【】的变化

000000000

001111111

111222222

111233333

111233334

122233334

f【】的差分变化

000000000

001000000

100100000

100110000000110001

110010001

100110001

这样思路应该清晰了

顺便口胡一句 fhq treap 真的难调.......

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1e5+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
struct node{
node *l,*r;
int h,f,sz,rnd;
void init(){h=; sz=; rnd=rand();}
void up(){
sz=; f=h;
if(l) sz+=l->sz,f=f|(l->f);
if(r) sz+=r->sz,f=f|(r->f);
}
void split(node*&lw,node*&rw,int k){
if(!this){lw=; rw=; return ;}
int ls=l?l->sz:;
if(k<=ls){
l->split(lw,l,k);
rw=this;
}
else{
r->split(r,rw,k-ls-);
lw=this;
}
up();
}
}tr[*M],*rt;
node* merge(node*a,node*b){
if(!a) return b;
if(!b) return a;
if(a->rnd>b->rnd){
a->r=merge(a->r,b);
a->up();
return a;
}{
b->l=merge(a,b->l);
b->up();
return b;
}
}
void modify(node*&x){
if(!x||!(x->f)) return ;
if(x->l&&(x->l->f)) modify(x->l);
else if(x->h==){
if(x->l&&x->r) x=merge(x->l,x->r);
else if(x->l) x=x->l;
else x=x->r;
return ;
}
else modify(x->r);
x->up();
}
int mx,n,l,r,k,cnt=M,ans;
int query(node *x){
if(!x) return ;
int sum=x->h;
if(x->l) sum+=query(x->l);
if(x->r) sum+=query(x->r);
return sum;
}
int main()
{
// freopen("input.in","r",stdin);
for(int i=;i<=M;i++) tr[i].init(),rt=merge(rt,tr+i);
n=read(); l=read(); r=read();
for(int i=;i<=n;i++){
k=read();
if(k) mx=max(mx,k);else mx=max(mx,r);
tr[++cnt].init();
tr[cnt].h=tr[cnt].f=;
node *p1,*p2,*p3;
if(!k){
rt->split(p2,p3,r-);
p2->split(p1,p2,l-);
modify(p3);
rt=merge(merge(p1,tr+cnt),merge(p2,p3));
}
else{
rt->split(p1,p2,k-);
modify(p2);
rt=merge(merge(p1,tr+cnt),p2);
}
}
node *p1,*p2;
rt->split(p1,p2,mx);
ans=query(p1);
printf("%d\n",ans);
return ;
}

汕头市队赛 SRM 07 D 天才麻将少女kpm的更多相关文章

  1. 汕头市队赛 SRM 07 B 好玩的麻将

    B 好玩的麻将 SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂.     KPM上周又打了n场麻将,又控了分使得自己的排名是1..n的一个排列.     但她 ...

  2. 汕头市队赛 SRM 07 C 整洁的麻将桌

    C 整洁的麻将桌 SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂.     KPM上周双打了n场麻将,但她这次没控分,而且因为是全民参与的麻将大赛,所以她的名 ...

  3. 汕头市队赛 SRM 07 A 你的麻将会排序吗

    A 你的麻将会排序吗 SRM 07 曾经有过一些沉迷日麻的小孩纸,后来呀,他们都去寻找自己的世界了. kpm也是这样的小孩纸.他想有一只自动整理牌的机器.当麻将以给定的顺序进入机器时,通过机器的运转, ...

  4. 汕头市队赛 SRM 06 B 起伏的排名

    B 起伏的排名 SRM 06 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂.     在上个星期她打了n场麻将,每场麻将都有n名玩家.KPM自然记得自己的n次排名.   ...

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

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

  6. CH暑假欢乐赛 SRM 07 天才麻将少女KPM(DP+treap)

    首先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 ...

  7. 汕头市队赛SRM 20 T2不净的圣杯

    不净的圣杯 SRM 20 背景 作为一张BUG级别的卡,官方打算把它修改得人畜无害一些…… 虽然名字还没想好,但是能力大概是对敌方所有单位造成d点伤害,d为自己牌组中所有卡的编号的最大公约数.这无疑是 ...

  8. 汕头市队赛 SRM 06 C 秀恩爱

    C 秀恩爱 SRM 06 背景&&描述         KPM坐在直升机上俯瞰小渔村景象.         渔村可看作二维平面,密密麻麻地到处都是单身狗,KPM当前所在坐标为(sx,s ...

  9. 汕头市队赛 SRM 06 A 撕书

    A 撕书 SRM 06 背景&&描述 游行寺汀正在杀书.         书总共有n页,每页都可以看作是一个小写英文字母,所以我们可以把书看成长度为n的字符串s.         琉璃 ...

随机推荐

  1. 选择 Delphi 2007 ( CodeGear Delphi 2007 for Win32 Version 11.0.2837.9583 ) 的理由

    选择 Delphi 2007 ( CodeGear Delphi 2007 for Win32 Version 11.0.2837.9583 ) 的理由 我不喜欢用InstallRite的全自动安装包 ...

  2. js簡介

    js是腳本語言: js適用於服務器.pc.平板電腦.智能手機: js是最流行的編程語言,使用與html和前段: js是一種輕量級編程語言: js能被所有的現代瀏覽器執行: js和java是完全不同的編 ...

  3. httprequest存储的是字符内容 而文本内容是以字节形式上传的;所以普通的取值方式无法从httprequest取到值

    httprequest存储的是字符内容 而文本内容是以字节形式上传的;所以普通的取值方式无法从httprequest取到值

  4. FieldGroup绑定的日期类型存储格式的问题

    问题 日期存储的时候,当前数据库中存储格式为 "2017-9-5 0:00:00", 而我实现了以后,看到数据库的存储格式为 "Mon Sep 04 00:00:00 C ...

  5. luogu3385 负环 (spfa)

    我在做spfa的时候,如果有一个点被更新了超过N次,证明这个图里是有负环的. (神TM输出YE5和N0) #include<bits/stdc++.h> #define pa pair&l ...

  6. Java NIO -- 缓冲区(Buffer)的数据存取

    缓冲区(Buffer): 一个用于特定基本数据类型的容器.由 java.nio 包定义的,所有缓冲区都是 Buffer 抽象类的子类.Java NIO 中的 Buffer 主要用于与 NIO 通道进行 ...

  7. Mac上配置idea的项目上传到GitHub

    1.安装git,Mac默认已经安装了Git,可以通过命令git —version查询一下. 2.创建SSH KEY(如果已经创建过,则不用再次创建.查看~/.ssh/id_rsa.pub是否存在) 生 ...

  8. Spring的后置处理器BeanFactoryPostProcessor

    新建一个JavaBean UserBeanFactoryPostProcessor 实现了BeanFactoryPostProcessor接口 Spring配置文件如下: 编写测试用例 从结果可以看出 ...

  9. 忘记ios访问限制密码

    1.使用iTunes将手机备份在本地. 2.下载iBackupBot,打开后在左侧可以看到你的历史备份,选择刚刚备份的文件.依次选择System Files -> HomeDomain -> ...

  10. [hihocoder1509][异或排序]

    hihocoder1509 思路 对于每两个数,从二进制的高位到低位考虑,发现,若前面一个的当前位是1,后面一个的当前位置是0,那么s的当前位置必须是1.反之,若前面是0,后面是1,那么s的当前位置必 ...