【atcoder】GP 2 [agc036C]
题目传送门:https://atcoder.jp/contests/agc036/tasks/agc036_c
题目大意:给你一个长度为$N$初始全0的序列,每次操作你可以找两个不同的元素,一个自增1,一个自增2,问$M$次操作后,能出现多少种不同的序列。
这道题比赛时分析的时候漏条件了,导致最后一个样例一直过不去,不过考虑上漏掉的条件分析起来也是比较复杂的。
我们可以发现如果一个序列$a$是合法的,当且仅当它满足以下条件:
1. $\sum_{i=1}^{N} a_i=3M$。
2. 整个序列里至多有$M$个奇数。
3. $\max_{i=1}^{N} a_i<=2M$。
证明可以考虑对$M$数学归纳。
我们可以先忽略条件3,枚举奇数的个数$i$,那么就是相当于对于一个全是偶数的数列,选择$i$个加上1,总方案数为$\sum_{i=1}^{\min(N,M)}\binom{N}{i}\binom{N-1+3M-i}{N-1}$,可以在$O(n+m)$的时间复杂度下计算。
然后在考虑减去不满足条件3的方案数。由于序列中大于$2M$的元素最多只有一个,因此我们可以钦定那个大于$2M$的元素为$a_1$,并将其减去$2M$,这样操作后的序列,并且原序列如果满足原序列是满足条件1,2,不满足条件3,当且仅当操作后的序列满足以下条件:
a. $\sum_{i=1}^{N} a_i=3M$。
b. 整个序列至多有$M$个奇数。(减去$2M$不改变奇偶性)
c. $a_1>0$。
我们再把这些方案看作两部分相减:忽略条件c的方案减去考虑条件c非法的答案,而我们发现这样的忽略条件c的方案条件与上面的条件1,2相似,可以用相似方法统计,而考虑条件c时因为钦定$a_1=0$,所以直接序列整体平移,$N$自减1再统计即可。
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define mod 998244353
#define Mod1(x) (x>=mod?x-mod:x)
#define Mod2(x) (x<0?x+mod:x)
#define maxn 3000010
inline ll read()
{
ll x=; char c=getchar(),f=;
for(;c<''||''<c;c=getchar())if(c=='-')f=-;
for(;''<=c&&c<='';c=getchar())x=x*+c-'';
return x*f;
}
inline void write(ll x)
{
static int buf[],len; len=;
if(x<)x=-x,putchar('-');
for(;x;x/=)buf[len++]=x%;
if(!len)putchar('');
else while(len)putchar(buf[--len]+'');
}
inline void writeln(ll x){write(x); putchar('\n');}
inline void writesp(ll x){write(x); putchar(' ');}
ll fac[maxn],inv[maxn];
int n,m;
inline ll power(ll a,ll b)
{
ll ans=;
for(;b;b>>=,a=a*a%mod)
if(b&)ans=ans*a%mod;
return ans;
}
inline ll C(int n,int m){return fac[n]*inv[m]%mod*inv[n-m]%mod;}
inline ll calc(int n,int m,int k)
{
ll sum=;
for(int i=;i<=n&&i<=k;i++)
if(!((m-i)&)&&m>=i)sum=(sum+C(n,i)*C((m-i)/+n-,n-))%mod;
// writeln(sum);
return sum;
}
int main()
{
n=read(); m=read();
fac[]=inv[]=;
for(int i=;i<=n+*m;i++){
fac[i]=fac[i-]*i%mod;
inv[i]=power(fac[i],mod-);
}
ll ans=(calc(n,*m,m)-n*(calc(n,m,m)-calc(n-,m,m)+mod))%mod;
writeln(Mod2(ans));
return ;
}
agc036C
【atcoder】GP 2 [agc036C]的更多相关文章
- 【AtCoder】ARC092 D - Two Sequences
[题目]AtCoder Regular Contest 092 D - Two Sequences [题意]给定n个数的数组A和数组B,求所有A[i]+B[j]的异或和(1<=i,j<=n ...
- 【Atcoder】CODE FESTIVAL 2017 qual A D - Four Coloring
[题意]给定h,w,d,要求构造矩阵h*w满足任意两个曼哈顿距离为d的点都不同色,染四色. [算法]结论+矩阵变换 [题解] 曼哈顿距离是一个立着的正方形,不方便处理.d=|xi-xj|+|yi-yj ...
- 【AtCoder】ARC 081 E - Don't Be a Subsequence
[题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...
- 【AtCoder】AGC022 F - Leftmost Ball 计数DP
[题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...
- 【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT
[题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模92484403 ...
- 【AtCoder】ARC067 F - Yakiniku Restaurants 单调栈+矩阵差分
[题目]F - Yakiniku Restaurants [题意]给定n和m,有n个饭店和m张票,给出Ai表示从饭店i到i+1的距离,给出矩阵B(i,j)表示在第i家饭店使用票j的收益,求任选起点和终 ...
- 【AtCoder】ARC095 E - Symmetric Grid 模拟
[题目]E - Symmetric Grid [题意]给定n*m的小写字母矩阵,求是否能通过若干行互换和列互换使得矩阵中心对称.n,m<=12. [算法]模拟 [题解]首先行列操作独立,如果已确 ...
- 【Atcoder】AGC022 C - Remainder Game 搜索
[题目]C - Remainder Game [题意]给定n个数字的序列A,每次可以选择一个数字k并选择一些数字对k取模,花费2^k的代价.要求最终变成序列B,求最小代价或无解.n<=50,0& ...
- 【Atcoder】AGC 020 B - Ice Rink Game 递推
[题意]n个人进行游戏,每轮只保留最大的a[i]倍数的人,最后一轮过后剩余2人,求最小和最大的n,或-1.n<=10^5. [算法]递推||二分 [题解]令L(i),R(i)表示第i轮过后的最小 ...
随机推荐
- [dart学习]第五篇:操作符
前言:本系列内容假设读者有一定的编程基础,如了解C语言.python等. 本节一起来学习dart的操作符,直接拷贝官网的操作符描述表如下: Description Operator unary pos ...
- UICollectionview的头视图和尾视图
UITableView有头视图和尾视图,那么UICollectionView有没有头视图和尾视图呢? 答案是有的. 1.新建一个类,必须继承自 UICollectionReusableView. 2. ...
- bat修改注册表
bat添加注册表,这里只是其中一部分,以后再补充.各项参数介绍的挺详细的,认真按照语法要求写就可以. reg add "HKCU\Software\Microsoft\Windows\Cur ...
- Flutter中通过循环渲染组件
class ContactsState extends State<Contacts>{ List formList; initState() { super.initState(); f ...
- 查看创世区块 Genesis Block和channel.tx文件
将 Block 详细内容导入到 json 文件查看 configtxgen -inspectBlock channel-artifacts/genesis.block > genesis.blo ...
- 转发表(MAC表)、ARP表、路由表总结
原文:https://cloud.tencent.com/developer/article/1173761 转发表(MAC表).ARP表.路由表总结 我是东东东 发表于我是东东强订阅 1.5K ...
- 《Java语言程序设计》异常处理
一.请阅读并运行AboutException.java示例,然后通过后面的几页PPT了解Java中实现异常处理的基础知识. 1. 源代码为: import javax.swing.*; class A ...
- 【ARM-Linux开发】U-Boot启动过程--详细版的完全分析
---------------------------------------------------------------------------------------------------- ...
- 记录一次SignalR服务端实现过程
前言:最近手上一个项目需要后端实时推送数据到前端,第一个想到的就是微软的SignalR,由于之前都是平时没事写的Demo,没有用到实际项目中,这次恰好用到了,因此记录下来整个实现过程(网上也有很多类似 ...
- codevs 1039:数的划分
http://codevs.cn/problem/1039/ 题目描述 Description将整数n分成k份,且每份不能为空,任意两种划分方案不能相同(不考虑顺序).例如:n=7,k=3,下面三种划 ...