Codeforces 1188E - Problem from Red Panda(找性质+组合数学)
咦,题解搬运人竟是我?
一道很毒的计数题。
先转化下题意,每一次操作我们可以视作选择一种颜色并将其出现次数 \(+k\),之后将所有颜色的出现次数 \(-1\)。我们假设第 \(i\) 种颜色被操作了 \(c_i\) 次,那么一组 \(\{c_1,c_2,\cdots,c_k\}\) 符合条件当且仅当 \(\forall i,a_i+kc_i\ge\sum\limits_{i=1}^kc_i\)。我们所求即是符合这样的条件的 \(\{a_i-kc_i-\sum\limits_{i=1}^kc_i\}\) 的个数。
直接统计显然不行,因此考虑发掘一些性质。一个非常自然的猜想是,如果操作不能无限进行下去,那操作最多进行的轮数不会太多,大概就 \(\mathcal O(k)\) 级别的,因为如果存在一种操作序列满足 \(k\) 步之后仍然不会挂,那么我们一直重复这 \(k\) 次操作的过程中即可将游戏一直进行下去。因此从这个角度入手作文章。考虑对于一种颜色 \(i\),如果我们希望操作能够继续下去,那么必然有前 \(a_i+1+ck\) 次操作中必须至少有 \(c+1\) 次操作作用在这个颜色上,因此我们考虑将数轴上这些形如 \(a_i+1+ck(c\ge 0)\) 的位置打上 \(+1\) 标记,然后对整个数轴进行一遍前缀和,我们假设得到的前缀和数组为 \(s_i\),如果我们发现某个 \(s_i\) 大于 \(i\),那么我们显然没办法安排这 \(i\) 次操作符合限制,也就表明操作次数最多为 \(i-1\),break 掉即可。如果对于 \(i\in[1,k-1]\) 都不存在这样的情况则说明操作可以无限进行下去。
考虑怎样统计答案,首先是有限次操作的情况。需要注意到一个性质,那就是对于所有 \(x,y\in[1,k-1]\),如果 \(x\ne y\),那么所有操作 \(x\) 次后得到的序列肯定不同于操作 \(y\) 次后得到的序列,因为至少要 \(k\) 次操作可以将一个序列复原,而根据上面的推论,有限次操作的情况中操作次数的上界为 \(k-1\),因此我们考虑枚举操作次数 \(x\),那么我们考虑统计 \(x\) 次操作可以产生多少组不同的 \(\{c_1,c_2,\cdots,c_k\}\)。这个可以通过调用我们之前求得的前缀和数组 \(s_x\) 计算:有 \(s_x\) 次操作选择的颜色已经确定了,因此我们只能安排剩余 \(x-s_x\) 次操作选择的颜色,而这等价于 \(\sum\limits_{i=1}^kd_i=x-s_x\) 的非负整数解的组数,隔板法可算得方案数为 \(\dbinom{x-s_x+k-1}{k-1}\)。对于所有 \(x\) 计算一遍上式的值并将答案加起来即可。
接下来是无限次操作的情况。首先注意到一个性质,就是由于操作可以无限进行下去,对于任意 \(p\),如果一个序列 \(\{a'\}\) 可以通过 \(p\) 次操作得到,那序列 \(\{a'\}\) 也可以通过 \(p+k\) 次操作得到。但这个结论反过来不一定成立,因为可能存在 \(p\) 过小而导致某些颜色无法操作的情况。不过这个问题比较容易解决,如果 \(p>\max{a_i}\) 就不会存在步数过小而无法操作全部颜色的情况了。因此直接对 \(x\in[10^6+1,10^6+k]\) 重复一遍上面的过程即可。
时间复杂度 \(\mathcal O(\max\{a_i\}+k)\)。
const int MAXN=1e6;
const int MOD=998244353;
int n,a[MAXN+5],cnt[MAXN*2+5],fac[MAXN*3+5],ifac[MAXN*3+5];
void init_fac(int n){
for(int i=(fac[0]=ifac[0]=ifac[1]=1)+1;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*ifac[i]%MOD;
}
int binom(int x,int y){
if(x<0||y<0||x<y) return 0;
return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;
}
int main(){
scanf("%d",&n);init_fac(MAXN*3);
int lim=n+MAXN,res=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
for(int j=a[i]+1;j<=lim;j+=n) cnt[j]++;
}
for(int i=1;i<=lim;i++){
cnt[i]+=cnt[i-1];
if(cnt[i]>i){lim=i-1;break;}
}
if(lim<=MAXN){
for(int i=0;i<=lim;i++) res=(res+binom(i-cnt[i]+n-1,n-1))%MOD;
} else {
for(int i=MAXN+1;i<=lim;i++) res=(res+binom(i-cnt[i]+n-1,n-1))%MOD;
}
printf("%d\n",res);
return 0;
}
Codeforces 1188E - Problem from Red Panda(找性质+组合数学)的更多相关文章
- Codeforces 1264F - Beautiful Fibonacci Problem(猜结论+找性质)
Codeforces 题面传送门 & 洛谷题面传送门 一道名副其实(beautiful)的结论题. 首先看到这道设问方式我们可以很自然地想到套用斐波那契数列的恒等式,注意到这里涉及到 \(F_ ...
- Codeforces 1383C - String Transformation 2(找性质+状压 dp)
Codeforces 题面传送门 & 洛谷题面传送门 神奇的强迫症效应,一场只要 AC 了 A.B.D.E.F,就一定会把 C 补掉( 感觉这个 C 难度比 D 难度高啊-- 首先考虑对问题进 ...
- Codeforces 1067E - Random Forest Rank(找性质+树形 dp)
Codeforces 题面传送门 & 洛谷题面传送门 一道不知道能不能算上自己 AC 的 D1E(?) 挺有意思的结论题,结论倒是自己猜出来了,可根本不会证( 开始搬运题解 ing: 碰到这样 ...
- Codeforces 809C - Find a car(找性质)
Codeforces 题目传送门 & 洛谷题目传送门 首先拿到这类题第一步肯定要分析题目给出的矩阵有什么性质.稍微打个表即可发现题目要求的矩形是一个分形.形式化地说,该矩形可以通过以下方式生成 ...
- Codeforces 1442D - Sum(找性质+分治+背包)
Codeforces 题面传送门 & 洛谷题面传送门 智商掉线/ll 本来以为是个奇怪的反悔贪心,然后便一直往反悔贪心的方向想就没想出来,看了题解才发现是个 nb 结论题. Conclusio ...
- Atcoder Grand Contest 008 E - Next or Nextnext(乱搞+找性质)
Atcoder 题面传送门 & 洛谷题面传送门 震惊,我竟然能独立切掉 AGC E 难度的思维题! hb:nb tea 一道 感觉此题就是找性质,找性质,再找性质( 首先看到排列有关的问题,我 ...
- Codeforces 1413F - Roads and Ramen(树的直径+找性质)
Codeforces 题目传送门 & 洛谷题目传送门 其实是一道还算一般的题罢--大概是最近刷长链剖分,被某道长链剖分与直径结合的题爆踩之后就点开了这题. 本题的难点就在于看出一个性质:最长路 ...
- Codeforces 526G - Spiders Evil Plan(长链剖分+直径+找性质)
Codeforces 题目传送门 & 洛谷题目传送门 %%%%% 这题也太神了吧 storz 57072 %%%%% 首先容易注意到我们选择的这 \(y\) 条路径的端点一定是叶子节点,否则我 ...
- Codeforces 698F - Coprime Permutation(找性质)
Codeforces 题面传送门 & 洛谷题面传送门 u1s1 感觉这个 D1F 比某道 jxd 作业里的 D1F 质量高多了啊,为啥这场的 D 进了 jxd 作业而这道题没进/yun 首先这 ...
随机推荐
- 【Docker】(11)---Docker的网络概念
一.实现原理 1.实现原理 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为C ...
- javascript-jquery-文档处理
一.移动元素 1.append():向每个匹配元素的内部追加内容.例如:$("选择器1").qppend("选择器2"):将会匹配选择器2的元素,移动到匹配选择 ...
- javascript运算符和表达式
1.表达式的概念 由运算符连接操作组成的式子,不管式子有多长,最终都是一个值. 2.算术运算符 加+ 减- 乘* 除/ 取模% 负数- 自增++ 自减-- 3.比较运算符 等于== 严格等于=== ...
- 【c++ Prime 学习笔记】目录索引
第1章 开始 第Ⅰ部分 C++基础 第2章 变量和基本类型 第3章 字符串.向量和数组 第4章 表达式 第5章 语句 第6章 函数 第7章 类 第 Ⅱ 部分 C++标准库 第8章 IO库 第9章 顺序 ...
- 【二食堂】Alpha - Scrum Meeting 6
Scrum Meeting 6 例会时间:4.16 11:40 - 12:10 进度情况 组员 昨日进度 今日任务 李健 1. 文本区域进度40%,UI需要进行调整issue 1. 继续文本区域的开发 ...
- 零基础入门C/C++实现你的浪漫表白:浪漫流星雨表白程序
想要讨女朋友欢心也巩固自己所学的知识,各位小伙伴有自己的想法了吗?准备好想要怎样实施了吗?有什么美好的计划了吗?如果没有的话那么别慌,我知道,在座的各位肯定都是有自己的心仪的姑娘,那么今天就教大家一招 ...
- SkyWalking配上告警更优秀
前言 对于监控系统来说,不可能让人一直盯着监控看板,而更多的是以自动提醒的方式,比如邮件.短信或微信推送等,当达到或超出预设的告警指标时,就自动发送消息提醒,下面就来说说如何配置SkyWalking的 ...
- Luogu P3758 [TJOI2017]可乐 | 矩阵乘法
题目链接 让我们先来思考一个问题,在一张包含$n$个点的图上,如何求走两步后从任意一点$i$到任意一点$j$的方案数. 我们用$F_p(i,j)$来表示走$p$步后从$i$到$j$的方案数,如果存储原 ...
- 手把手教你学Dapr - 4. 服务调用
上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...
- 『学了就忘』Linux基础命令 — 20、文件操作的相关命令
目录 1.touch 命令 2.stat命令 3.cat命令 4.more命令 5.less命令 6.head命令 7.tail命令 1.touch 命令 touch命令用于创建空文件或修改文件时间, ...