汕头市队赛 SRM 07 D 天才麻将少女kpm
这道题放了很久还是回来补了
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的更多相关文章
- 汕头市队赛 SRM 07 B 好玩的麻将
B 好玩的麻将 SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂. KPM上周又打了n场麻将,又控了分使得自己的排名是1..n的一个排列. 但她 ...
- 汕头市队赛 SRM 07 C 整洁的麻将桌
C 整洁的麻将桌 SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂. KPM上周双打了n场麻将,但她这次没控分,而且因为是全民参与的麻将大赛,所以她的名 ...
- 汕头市队赛 SRM 07 A 你的麻将会排序吗
A 你的麻将会排序吗 SRM 07 曾经有过一些沉迷日麻的小孩纸,后来呀,他们都去寻找自己的世界了. kpm也是这样的小孩纸.他想有一只自动整理牌的机器.当麻将以给定的顺序进入机器时,通过机器的运转, ...
- 汕头市队赛 SRM 06 B 起伏的排名
B 起伏的排名 SRM 06 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂. 在上个星期她打了n场麻将,每场麻将都有n名玩家.KPM自然记得自己的n次排名. ...
- 【SRM-07 D】天才麻将少女KPM
Description 天才麻将少女KPM立志要在日麻界闯出一番名堂.KPM上周叒打了n场麻将,但她这次又没控分,而且因为是全市参与的麻将大赛,所以她的名次范围是0..10^5.名次可能等于0是因为K ...
- 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 ...
- 汕头市队赛SRM 20 T2不净的圣杯
不净的圣杯 SRM 20 背景 作为一张BUG级别的卡,官方打算把它修改得人畜无害一些…… 虽然名字还没想好,但是能力大概是对敌方所有单位造成d点伤害,d为自己牌组中所有卡的编号的最大公约数.这无疑是 ...
- 汕头市队赛 SRM 06 C 秀恩爱
C 秀恩爱 SRM 06 背景&&描述 KPM坐在直升机上俯瞰小渔村景象. 渔村可看作二维平面,密密麻麻地到处都是单身狗,KPM当前所在坐标为(sx,s ...
- 汕头市队赛 SRM 06 A 撕书
A 撕书 SRM 06 背景&&描述 游行寺汀正在杀书. 书总共有n页,每页都可以看作是一个小写英文字母,所以我们可以把书看成长度为n的字符串s. 琉璃 ...
随机推荐
- MES模块
基础数据管理:产品模型.工厂模型.工艺模型 仓储管理 成本管理 绩效管理 看板管理 日志管理 设备管理:工装管理.设计器具管理.设备保养管理.设备备件管理.设备采集管理.设备点检管理.设备故障管理.设 ...
- 转载《ionic 热更新 cordova-hot-code-push》
cordova-hot-code-push ,Cordova热代码推送插件提供了在应用程序中执行基于Web的内容的自动更新的功能.使用此插件可以更新存储在项目的www文件夹中的所有内容. cordov ...
- JavaScript中的Date对象在IOS中的“大坑”
在IOS5以上版本(不包含IOS5)中的Safari浏览器能正确解释出Javascript中的 new Date('2013-10-21') 的日期对象. 但是在IOS5版本里面的Safari解释ne ...
- poj 1904(强连通分量+输入输出外挂)
题目链接:http://poj.org/problem?id=1904 题意:有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国 ...
- 买了本Delphi面向对象编程思想,正在看,产生些问题。
1:第33页说,Delphi通过调用类的一个构造函数来建立一个对象的实例,对象至少有一个create()的构造函数,使用时候写MyObject:=TmyObject.create即可. 但是第37 ...
- hihocoder部分题解
hihocoder1609 数组分拆II [dp] 给定数组,问有多少种拆法,使得每一段不出现重复的数字,且要保证分组数最少.(1e5) 题解: O(n) d[i]表示1~i最小划分的段数, f[i] ...
- Leetcode 1.两数之和 By Python
思路 很容易想到的方法是二重循环遍历一遍,但是会很慢 把加法变减法可以大大加速 代码 class Solution: def twoSum(self, nums, target): "&qu ...
- 学习Spring Boot:(二十二)使用 AOP
前言 AOP 1,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.基于AOP实现的功能不会破坏原来程序逻辑,因此它可以很好的对业务逻辑的各个部分进行隔离,从而使得业 ...
- luogu2774 [网络流24题]方格取数问题 (最小割)
常见套路:棋盘黑白染色,就变成了一张二分图 然后如果选了黑点,四周的白点就不能选了,也是最小割的套路.先把所有价值加起来,再减掉一个最少的不能选的价值,也就是割掉表示不选 建边(S,黑点i,v[i]) ...
- Centos7下安装python3
1. 安装依赖环境 # yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline- ...