首页 > 其他分享 >CF1753C题解

CF1753C题解

时间:2024-11-26 10:23:32浏览次数:9  
标签:cnt frac int 题解 个数 CF1753C MAXN dp

鲜花

被卡了一万年。

考虑过序列变换的各种情况和逆序对,结果这俩情况状态太多,而且相同逆序对 ans 也不一定相同。/ll

sol

我们最后想要的状态为所有 \(0\) 都在 \(1\) 的左边,令 \(cnt_0\) 为 \(0\) 的个数,\(cnt_1\) 为 \(1\) 个数。
\(cnt_0+cnt_1=n\),结束的状态前 \(cnt_0\) 个数均为 \(0\),后 \(cnt_1\) 个数均为 \(1\)。

其余状态会有 \(0\) 混入后 \(cnt_1\) 个数中,\(1\) 混入前 \(cnt_0\) 个数中,可以视作由结束的状态交换得到,这些 \(0\) 与 \(1\) 的数量是等价的,记为 \(m\)。

将前 \(cnt_0\) 个数和后 \(cnt_1\) 个数视为两部分,其内部的交换不能影响 \(m\),而结束的状态即 \(m\) 为 \(0\),每次进行交换要么不影响 \(m\),要么将 \(m\) 减 \(1\),我们进行分类讨论后在这个思路上进行转移。

思路卡住的地方,就是这里,没有将前 \(cnt_0\) 个数和后 \(cnt_1\) 个数视为两部分,恒以为有交换和无交换是不同的,根本想不到上面。
所以做题不要死磕,实在不行就打暴力。

有效的交换为前 \(cnt_0\) 中的 \(1\) 与后 \(cnt_1\) 中的 \(0\) 进行交换,当 \(m=i\) 时,共 \(i^2\) 个,无效的为 \(C_n^2-i^2\),令 \(dp_i\) 为 \(m=i\) 时的期望操作次数,\(dp_i=(\frac{i^2}{C_n^2}dp_{i-1}+\frac{C_n^2-i^2}{C_n^2}dp_i)+1\),整理得 \(dp_i=dp_{i-1}+\frac{C_n^2}{i^2}\)。

易得 \(dp_0=0\),通过数学归纳法得 \(dp_m=C_n^2\sum\limits_{i=1}^m\frac{1}{i^2}\)。

\(O(n)\) 求得逆元,后循环加起来做乘法即为答案。

代码如下。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
constexpr int MAXN=2e5+10,MOD=998244353;
int n,a[MAXN],cnt0,m,inv[MAXN],jc[MAXN],jcinv[MAXN];
namespace sol{
	void solve(){
		cnt0=m=0;
		scanf("%d",&n);
		for(int i=1;i<=n;++i){
			scanf("%d",&a[i]);
			if(!a[i])++cnt0;
		}
		for(int i=1;i<=cnt0;++i){
			if(a[i])++m;
		}
		int ans=0;
		for(int i=1;i<=m;++i){
			ans=(1ll*ans+(1ll*inv[i]*inv[i]%MOD))%MOD;
		}
		ans=(1ll*ans*((1ll*n*(n-1)/2)%MOD))%MOD;
		printf("%d\n",ans);
	}
}
int qpow(int x,int y){
	int ret=1;
	while(y){
		if(y&1)ret=1ll*ret*x%MOD;
		x=1ll*x*x%MOD;
		y>>=1;
	}
	return ret;
}
int main(){
	int T;scanf("%d",&T);
	jc[0]=1;
	for(int i=1;i<=(int)(2e5);++i){
		jc[i]=1ll*jc[i-1]*i%MOD;
	}
	jcinv[(int)(2e5)]=qpow(jc[(int)(2e5)],MOD-2);
	for(int i=(int)(2e5)-1;i;--i){
		jcinv[i]=1ll*jcinv[i+1]*(i+1)%MOD;
	}
	for(int i=1;i<=(int)(2e5);++i){
		inv[i]=1ll*jcinv[i]*jc[i-1]%MOD;
	}
	while(T--)sol::solve();
	return 0;
}

标签:cnt,frac,int,题解,个数,CF1753C,MAXN,dp
From: https://www.cnblogs.com/LiJoQiao/p/18569507

相关文章

  • P5572 [CmdOI2019] 简单的数论题 题解
    题目描述\(T\)组数据,给定\(n\gem\),求:\[\sum_{i=1}^n\sum_{j=1}^m\varphi(\frac{\text{lcm}(i,j)}{\gcd(i,j)})\\\]对\(23333\)取模。数据范围\(1\leT\le3\cdot10^4,1\lem\len\le5\cdot10^4\)。时间限制\(\texttt{2s}\),空间限制\(\texttt{128......
  • ARC188B - Symmetric Painting 题解
    很启发的题目,考虑每次绘画的点。Alice绘画\(-x\)点。Bob绘画\(2K-x\)点。按顺序绘画\(0,2K,-2K,4K,-4K,6K,-6K,\ldots\),由于模\(n\)的完全剩余系在互质的乘法中封闭,也就是说\(N\)与\(2K\)互质时可以取遍所有数。再考虑\(\gcd(N,2K)\ne1\)时,......
  • [ABC234G] Divide a Sequence (DP+单调栈)题解
    分析题意十分简单,不难推出式子:$f_i=\sum_{j=1}^{i-1}f_j\times(\max_{k=j+1}^ia_k-\min_{k=j+1}^ia_k)$但我们考虑这个\(O(n^2)\)的东西显然是冲不过去的,所以必须优化转移。式子后面两块都是极值,这启发我们用单调栈解决。由于\(\max_{k=j+1}^i\)与\(\min_{k=......
  • CF2093 B/C题解
    B.ShohagLovesStrings注意到两个相同字母aa的\(f(p)\)为偶数,所以如果找到两个相邻相同字母输出即可。如果没有相邻相同的两个字母,则说明字符串相邻的字母一定不同,再考察三个相邻的字母的情况,发现三个字母均不同,如abc时\(f(p)\)也为偶数,又找到一种合法的情况。那么剩下......
  • ZZJC新生组队赛第十一场题解
    A苏醒,浮出梦乡定义\(s_n^m\)为\(\{a_n\}\)的\(m\)阶前缀和数组第\(n\)位上的值显然\(s_n^m=s_{n-1}^m+s_n^{m-1}\)自然的,我们可以朴素的进行DP算出\(s_n^m\)的最大可能值然而计算一下复杂度却发现是\(n^2\),显然会TLE,不优化的话还会MLE但是根据输入,易得......
  • ZZJC新生训练赛第十八场题解
    链接:https://www.nowcoder.com/acm/contest/97429密码:gar615gdsr难度分类题目分值决定A-解题思路除一下比较分数大小即可A-代码实现a,b=map(int,input().split())x,y=map(int,input().split())ifa/b>x/y:print(">")elifa/b==x/y:prin......
  • 【题解】洛谷P5911 :[POI2004] PRZ
    状压dp,先预处理出来所以状态的重量和时间,然后枚举集合,然后枚举子集,子集重量合法的话就可以转移,因为这题是多个集合组成最后的集合。枚举子集。https://oi-wiki.org/math/binary-set/#__tabbed_1_1#include<bits/stdc++.h>#defineintlonglong#definelsp<<1#definersp......
  • easyui combobox 只能选择第一个问题解决
    easyuicombobox只能选择第一个问题解决问题现象在拆分开票的时候,弹出框上面有一个下拉框用于选择需要新增的明细行,但是每次只能选择到第一个选择第二条数据的时候默认选择到第一个了代码如下/*新增发票编辑窗口*/functionaddTicketDialog(){orderIte......
  • CF2023C C+K+S 题解
    前置知识:哈希/KMP题目链接:洛谷、Codeforces。有点牛的一道题。首先,既然两张图所有的环长都是\(k\)的倍数,那么考虑做一个比较厉害的处理:对图染色。令\(u\)的颜色为\(c_u\),如果有边\(u\rightarrowv\),那么\(c_v=(c_u+1)\modk\)。这样最多有\(k\)种颜色,范围是\(......
  • AtCoder ABC321F - #(subset sum = K) with Add and Erase 题解 可撤销背包
    题目链接:https://atcoder.jp/contests/abc321/tasks/abc321_f题目大意:给定大小为\(k\)的背包和\(q\)次操作,支持两种操作:插入一个大小为\(x\)的元素;删除一个大小为\(x\)的元素。每次操作后,求装满背包方案数。解题思路:可撤销背包。插入\(x\)时,fori=K->x......