汕头市队赛 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+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
struct node{
    node *l,*r;
    int h,f,sz,rnd;
    void init(){h=0; sz=1; rnd=rand();}
    void up(){
        sz=1; 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=0; rw=0; return ;}
        int ls=l?l->sz:0;
        if(k<=ls){
            l->split(lw,l,k);
            rw=this;
        }
        else{
            r->split(r,rw,k-ls-1);
            lw=this;
        }
        up();
    }
}tr[2*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==1){
        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 0;
    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=1;i<=M;i++) tr[i].init(),rt=merge(rt,tr+i);
    n=read(); l=read(); r=read();
    for(int i=1;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=1;
        node *p1,*p2,*p3;
        if(!k){
            rt->split(p2,p3,r-1);
            p2->split(p1,p2,l-1);
            modify(p3);
            rt=merge(merge(p1,tr+cnt),merge(p2,p3));
        }
        else{
            rt->split(p1,p2,k-1);
            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 0;
}

时间: 2024-08-01 10:42:48

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

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

A 你的麻将会排序吗 SRM 07 曾经有过一些沉迷日麻的小孩纸,后来呀,他们都去寻找自己的世界了. kpm也是这样的小孩纸.他想有一只自动整理牌的机器.当麻将以给定的顺序进入机器时,通过机器的运转,使得麻将们出机器的顺序是递增的.所以kpm需要在机器中建立一些传送带 (假设这些传送带都是足够长,可以停放很多很多的麻将),问题是,现在kpm需要建立多少条传送带才能完成他的机器. kpm大概有10^5块麻将吧. 输入格式 第一行是一个不大于10^5的数,表述麻将的总数. 第二行是麻将依次进入机器的

汕头市队赛 SRM 09 A 撕书

A 撕书I-3 SRM 09 背景&&描述 琉璃在撕书.     书总共有n页,都悬浮在数轴上,第i页的位置为,上面写着一个数字.     琉璃从右往左撕书.假如看到了第i页,就把在第i页左边,且与之距离<=的书都撕掉.(第i页本身不撕)     夜子为了尽量地保全魔法书,决定偷偷在琉璃开始撕之前,增加一页.增加的这一页必须在所有书页的右边,数字随意.     夜子想知道,最少会有多少页书被撕毁. 输入格式 第一行一个整数n,表示书页数. 接下来n行,第i行的俩整数分别为和. 输出格

汕头市队赛 SRM 09 B 撕书

B 撕书II-3 SRM 09 背景&&描述 琉璃手头有一黑一白两本魔法书,一本是<缟玛瑙的不在证明>,另一本是<白色相簿1.5>     传说同时打开这两本书会有奇怪的事情发生.     琉璃打开一看,果然非常奇怪:两本书上都各自写着一个正整数(可能他买到盗版了),分别是a和b.     试图撕书的汀想借过来看看,但琉璃只告诉了他这俩数加起来的值x和异或起来的值y.     汀发现有很多种(a,b)满足琉璃告诉他的信息...你能帮他算出来有多少种吗? 输入格式 两

汕头市队赛 SRM 06 C 秀恩爱

C 秀恩爱 SRM 06 背景&&描述 KPM坐在直升机上俯瞰小渔村景象. 渔村可看作二维平面,密密麻麻地到处都是单身狗,KPM当前所在坐标为(sx,sy). KPM的后宫团们自发地聚集在一起为他送行,从空中看,后宫团形成了一个多边形. 当然了KPM是不在那个多边形内的. 直升机突然开始原地转圈,后宫团们因为想看着KPM的正脸,所以也跟着以KPM所在坐标为中心旋转. 后宫团所经之处单身狗尸横遍野.赶来救治伤员的医护人员想知道,多边形扫过的面积是多少. 注意,本题不保证横坐标互不相同.纵坐标

汕头市队赛 SRM 09 C 撕书

C 撕书III-3 SRM 09 背景&&描述 琉璃双在撕书.     书总共有n页,每页都可以看作是一个数字.     琉璃读书喜欢来回地读.但他也因此发现了作者的灌水行为:有些连续的若干页正着读和倒着读完全一样,也就是说是回文的.     发生这种情况时,琉璃会非常地angry,把那些书页给撕掉.     汀捡到了本黑色的魔法书.因为担心杀死书后会带来麻烦,决定借琉璃的手把书处置掉.     大概就是每次选出剩余书页中的一个回文子串,拿给琉璃看....     汀比较懒,他想知道最少选

汕头市队赛 SRM 08 B

B-3 SRM 08 描述 给长度为 n 的数列 A 和长度为 m 的数列 B,问有多少长度为 m 的数列 C 满足 输入格式 第一行俩整数 n 和 m 第二行 n 个整数 ,表示数列 A 第三行 m 个整数 ,表示数列 B 输出格式 一个整数,表示满足条件的数列 C 的个数模  后的值. 样例输入 1 5 3 1 5 2 4 7 7 9 6 样例输出 1 4 样例输入 2 4 2 7 7 7 7 3 4 样例输出 2 6 数据范围与约定 样例解释 第一个样例中,数列 C 可以为 (1, 3,

汕头市队赛 C KMP codeforces B. Image Preview

汕头市队赛题目传送门 codeforces题目传送门 这道题我的做法是 尝试先往左走然后往右走 或者先往右走然后往左走 然后注意一下枚举顺序就okay啦 #include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=1e6+7; LL read(){ LL ans=0,f=1,c=getchar(); while(c

汕头市队赛SRM15

T1--czl SRM 15 众所周知,czl家养了一只可♂爱的***(已屏蔽),那只东西很贪吃,所以czl家很多零食仓库,然而这些仓库里有很多老鼠. 为了心爱的***,czl决定点燃纯艾条,用烟熏老鼠. 共有N个仓库,编号1-N. 假设陵陵在第i个仓库点燃艾条,烟雾就会充满该仓库,并向左右扩散Ai 的距离,接着所有|i-j|<=Ai 的仓库 j 的老鼠被消灭. 陵陵是个爱护环境的人,他想知道最少需要多少支艾条,才可以消灭所有老鼠. [输入格式] 第一行:一个正整数,代表 N. 第二行:N 个非

汕头市队赛 SRM1X T2 ——扫描线

绵津见-终 SRM 13 背景 "西瓜也是可以种在海上的!"--绵津见 然而种在海上的西瓜最需要防范的,是时不时会涌向瓜田的阵阵海浪. 幸好,身为海神的绵津见可以释放魔法"水平如镜"来阻止海浪拍打西瓜. 然而,当西瓜一个接一个成熟之时,它们就要离开瓜田,飘向遥远的彼岸.绵津见的魔法无法保护离开瓜田的西瓜们,但至少,也得知道西瓜们遭遇了多大的风浪啊. 描述 我们用一个坐标系来描述大海,绵津见的瓜田位于x轴下方,每当有一个西瓜成熟时,它会从x轴上一点出发,沿一条平行y轴