ABC267G Increasing K Times 题解
做这道题,很有感悟,发篇文。
先给数列从小到大排个序。
接下来设 \(f_{i,j}\) 表示前 \(i\) 个数的排列形成 \(j\) 个上坡的方案数。
接下来考虑转移,分为插入第 \(i\) 个数后增加上坡和不增加上坡两种情况。
对于不增加的情况,有三种可能:
- 第 \(i\) 个数插入在了数列的最前端,有 \(1\) 种方案。
 - 第 \(i\) 个数插入在了一个上坡的中间,因为上坡中较小的那个数字必定小于第 \(i\) 个数,形成一个上坡,较大的那个数字必定小于等于第 \(i\) 个数,不形成上坡,而我们拆散了一个上坡,故没有增加,有 \(j\) 种方案。
 - 第 \(i\) 个数插入在了数值相同的数后面,这个记为 \(same_i\),有 \(same_i\) 种方案。
 
对于增加的情况,就是减去这三种情况了,不过增加了,就说明原来只有 \(j-1\) 个上坡,这里和上面不太一样。
整理式子,得:
\]
这样就可以 \(O(n^2)\) 求得了,可以用滚动数组。
#include <bits/stdc++.h>
using namespace std;
long long n, k, a[5005], f[5005], same[5005], sum;
int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) {
        if (a[i] == a[i - 1])
            same[i] = same[i - 1] + 1;
    }
    f[0] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = i - same[i]; j >= 1; j--) {
            f[j] = f[j - 1] * (i - j - same[i]) % 998244353 + f[j] * (1 + j + same[i]) % 998244353;
            f[j] %= 998244353;
        }
        f[0] = f[0] * (1 + same[i]) % 998244353;
    }
    cout << f[k] << endl;
}
After Increasing K Times
过了一段时间重新看了一下这道题,发现有几个优化,也顺便介绍一下。
首先,我们发现 \(n\) 很大,但是数值区间很小,所以考虑使用桶排序,因为数字在 \([1,n]\),所以排序复杂度为 \(O(n)\)。
然后,我们发现枚举区间可以缩小,因为我们并不是全都需要,简单用一个图表示:

左边是我们需要的值,右边是不需要的。
那么,有用的状态的区间边界很好推算,是 \([k+n-i+1,k]\),这个优化可以减少接近一半的时间。
以上优化让代码大大提速,获得了洛谷最优解,在 AtCoder 排名第二(截至2022.11.23)。
第一名本人丧心病狂卡常也卡不过,快了 4ms,但是本代码很短,最快代码使用了 IDFT。
#include <stdio.h>
inline int read() {
    char c = getchar();
    int sum = 0;
    while (c < '0' || c > '9') c = getchar();
    do {
        sum = (sum << 3) + (sum << 1) + c - '0';
        c = getchar();
    } while (c >= '0' && c <= '9');
    return sum ;
}
int n, k,s[5005],b[5005],t=1;
long long f[5005];
int main() {
    n=read(),k=read();
    for (int i = 1; i <= n; i++)b[read()]++;
    for(int i=1;i<=n&&t<=n;i++)
    {
    	if(b[i])b[i]--,t++;
    	while(b[i])b[i]--,s[t] = s[t - 1] + 1,t++;
	}
    f[0] = 1;
    for (int i = 1; i <= n; i++) {
		int r=(k>i-s[i])?(i-s[i]):k,l=(k-n+i-1>1)?(k-n+i-1):1;
        for (int j = r; j >= l; j--) {
            f[j] = f[j] * (j + s[i] + 1) + f[j - 1] * (i - j - s[i]) ;
            f[j] %= 998244353;
        }
        f[0] = f[0] * (s[i] + 1) % 998244353;
    }
    printf("%lld\n",f[k]);
    return 0;
}
												
											ABC267G Increasing K Times 题解的更多相关文章
- OJ2237第k小数题解
		
题目描述: 有n个数,请你找出第k小的数. 输入描述: 第一行有2个正整数n,k(n,k<=10^7)第二行有n个非负数ai(ai<=10^5) 输出描述: 输出第k小的数. 输入样例: ...
 - 9.1练习题5 差k素数对 题解
		
题目出处:洛谷 P1348 ,题面略有改编. 题目描述 给你两个数 n 和 k ,请求出所有小于等于 n 的相差为 k 的素数对. 输入格式 两个正整数n,k.1<=k<=n<=10 ...
 - 排序入门练习题3 谁考了第k名 题解
		
题目出处:<信息学奥赛一本通>第二章 上机练习1 题目描述 在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名的学生的学号和成绩. 输入格式 输入的第一行包含两 ...
 - 2018ICPC网络赛(焦作站)K题题解
		
一.题目链接 https://nanti.jisuanke.com/t/31720 二.题意 给$N$种船只,第$i$种船的载重量是$V_i$,数量是$2^{C_i}-1$.接下来有$Q$次询问,每次 ...
 - POJ2104 区间第k小
		
题意就是区间第k大…… 题解: 前段时间用主席树搞掉了…… 如今看到划分树,是在想来写一遍,结果18号对着学长的代码调了一上午连样例都没过,好桑心…… 今天在做NOI2010超级钢琴,忽然发现用划分树 ...
 - Codeforces Round #460 (Div. 2) ABCDE题解
		
原文链接http://www.cnblogs.com/zhouzhendong/p/8397685.html 2018-02-01 $A$ 题意概括 你要买$m$斤水果,现在有$n$个超市让你选择. ...
 - HDU 5977 Garden of Eden(点分治求点对路径颜色数为K)
		
Problem Description When God made the first man, he put him on a beautiful garden, the Garden of Ede ...
 - BUPT2017 wintertraining(15) #2 题解
		
这场有点难,QAQ.补了好久(。• ︿•̀。) ,总算能写题解了(つд⊂) A. Beautiful numbers CodeForces - 55D 题意  求\([l,r](1\le l_i\l ...
 - Moscow Subregional 2013. 部分题题解 (6/12)
		
Moscow Subregional 2013. 比赛连接 http://opentrains.snarknews.info/~ejudge/team.cgi?contest_id=006570 总叙 ...
 - 【codeforces】【比赛题解】#915 Educational CF Round 36
		
虽然最近打了很多场CF,也涨了很多分,但是好久没写CF的题解了. 前几次刚刚紫名的CF,太伤感情了,一下子就掉下来了,不懂你们Div.1. 珂学的那场我只做了第一题……悲伤. 这次的Education ...
 
随机推荐
- habse与Hadoop兼容性问题
			
今天大数据实验课被血坑,在第一步hbase的安装时就卡住了,之后处理了一整节实验课,也未能解决,回到宿舍后才解决(这里不得不说"度娘"不行了,出现的问题完全找不到,最好还是在chr ...
 - Windows快捷键学习
			
Ctrl组合 Ctrl+C 复制 Ctrl+X 剪切 Ctrl+V 粘贴 Ctrl+A 全选 Ctrl+Z 撤消 Ctrl+S 保存 Shift组合 Shift+Delete 永久删除 Shift+A ...
 - mysql根据一个表更新另外一个表
			
-- 语法:update table_1 t1,table_2 t2 set t1.column = t2.column where t1.id = t2.pid; UPDATE house_test ...
 - centos7开放8080端口
			
1. firewall-cmd --state :令防火墙处于开启状态 systemctl start firewalld.service: 2. firewall-cmd --zone=publi ...
 - boost编译指定python版本号
			
1.执行如下 bootstrap 语句,会在目录下生成 project-config.jam 文件 .\bootstrap --with-python="C:\Users\yzy\Anaco ...
 - Quine-McCluskey两级逻辑化简算法原理解析
			
转载请务必注明出处:https://www.cnblogs.com/the-wind/p/15764283.html 目录 1 背景介绍:两级逻辑 2 Quine-McCluskey两级逻辑化简 2. ...
 - gRPC之.Net6中的初步使用说明
			
1.介绍 GRPC是一个高性能.通用的开源远程过程调用(RPC)框架,基于底层HTTP/2协议标准和协议层Protobuf序列化协议开发,支持众多的开发语言,由Google开源. gRPC也是基于以下 ...
 - PicList 现已上架Mac App Store 分享下整个上架过程和遇到的问题
			
PicList 是一款云存储/图床平台管理和文件上传工具,基于 PicGo 进行了深度二次开发,保留了 PicGo 的所有功能的同时,为相册添加了同步云端删除功能,同时增加了完整的云存储管理功能,包括 ...
 - JAVA异步编程之Callbacks与Futures模型
			
JAVA异步编程之Callbacks与Futures模型 一:Callbacks模型  该模型的异步方法,在异步任务完成之后调用,主线程没有异步线程的结果.经典模型如Swing's EventLis ...
 - 这年头,谁的好友列表还没有躺一个ChatGPT啊?
			
你要是说这个,我可不困了 大家好,我最近开始使用一款非常有趣的AI机器人,它叫做ChatGPT.ChatGPT是一款独特的聊天机器人,它可以进行智能对话,回答你的问题,还可以学习你的语言习惯,使得对话 ...