首页 > 其他分享 >abc273G题解

abc273G题解

时间:2023-01-19 14:44:06浏览次数:50  
标签:tmp cnt int 题解 rep abc273G dp define

\(dp[i][j]\) :考虑到前 i 行,有 j 个 2 的方案数。

设有k个1(计算可得)。

  • \(a_{i+1} = 0\):

    \(dp[i][j] \to dp[i+1][j]\)

  • \(a_{i+1}=1\):

    \(dp[i][j]\times(n-j-k) \to dp[i + 1][j]\)

    \(dp[i][j]\times k \to dp[i + 1][j + 1]\)

  • \(a_{i+1}=2\):

    \(dp[i][j]\times \tbinom{n-j-k}{2} \to dp[i + 1][j]\)

    \(dp[i][j] \times (n - j - k) \times k \to dp[i + 1][j + 1]\)

    \(dp[i][j] \times \tbinom{k}{2} \to dp[i + 1][j + 2]\)

    \(dp[i][j] \times \tbinom{n-j-k}{1} \to dp[i][j+1]\)

\(\tbinom{n}{m} = \frac{n!}{(n-m)!m!}\)

AcCode:

#include <bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i = (int)l;i <= (int)r;i++)
#define per(i,r,l) for(int i = (int)r;i >= (int)l;i--)
#define pb push_back
#define all(a) a.begin(),a.end()
#define fi first
#define se second
#define mp make_pair
#define SZ(a) (int)(a.size())
#define random(l, r) (rand() * 1ll * rand() % (r - l + 1) + l)
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef long long ll;
typedef double db;

const int N = 1e4 + 10, inf = INT_MAX, P = 998244353;
int n;
int a[N], b[N], sum[N];
ll dp[N], tmp[N], f[N], inv[N];

ll rp(ll a, int b) {
	ll res = 1;
	for (; b; (a *= a) %= P, b /= 2)
		if (b & 1)
			(res *= a) %= P;
	return res;
}

void init() {
	f[0] = 1;
	rep(i,1,n) f[i] = f[i - 1] * i % P;
	rep(i,0,n) inv[i] = rp(f[i], P - 2);
}

ll C(int a, int b) {
	if (a < b) return 0;
	return f[a] * inv[a - b] % P * inv[b] % P;
}

int main() {
	scanf("%d", &n);
	init();
	int cnt = 0, t1 = 0, t2 = 0;
	rep(i,1,n) {
		scanf("%d", &a[i]);
		sum[i] = sum[i - 1] + a[i];
		t1 += a[i];
	}
	rep(i,1,n) {
		scanf("%d", &b[i]);
		cnt += (b[i] == 2);
		t2 += b[i];
	}
	if (t1 != t2) {
		puts("0");
		return 0;
	}
	tmp[0] = 1;
	rep(i,0,n - 1) {
		rep(j,0,n) {
			int k = sum[i] - j * 2;// k个1
			if (!tmp[j] || k < 0 || n - j - k < 0) continue;
			if (a[i + 1] == 0)
				(dp[j] += tmp[j]) %= P;
			else if (a[i + 1] == 1) {
				(dp[j] += tmp[j] * (n - j - k) % P) %= P;
				(dp[j + 1] += tmp[j] * k % P) %= P;
			} else {
				(dp[j] += tmp[j] * C(n - j - k, 2) % P) %= P;
				(dp[j + 1] += tmp[j] * (n - j - k) % P * k % P) %= P;
				(dp[j + 1] += tmp[j] * C(n - j - k, 1) % P) %= P;
				(dp[j + 2] += tmp[j] * C(k, 2) % P) %= P;
			}
		}
		rep(j,0,n) {
			tmp[j] = dp[j];
			dp[j] = 0;
		}
	}
	int _cnt = sum[n] - cnt * 2;
	ll ans = tmp[cnt];
	ans = ans * rp(C(n, cnt), P - 2) % P;
	ans = ans * rp(C(n - cnt, _cnt), P - 2) % P;
	printf("%lld\n", ans);
	return 0;
}

标签:tmp,cnt,int,题解,rep,abc273G,dp,define
From: https://www.cnblogs.com/Vancezyx/p/17061450.html

相关文章

  • win10下python3.9的代理报错问题解决(附web3的polygon爬虫源码)
    背景因为工作中经常需要代理访问,而开了代理,request就会报错SSLError,如下:requests.exceptions.SSLError:HTTPSConnectionPool(host='test-admin.xxx.cn',port=443):Ma......
  • C# 使用SQLDMO备份数据库时不显示进度的问题解决方法
    在使用SQLDMO备份数据库的过程中,参考了网上的例子,但是进度条却不显示,每次返回的都是0,解决方法是使用全局变量,每次做个累加就可以了。stringServerName="";......
  • Nextcloud安装扩展记录以及问题解决方法
    1、Nextcloud支持显示视频缩略图-23-01-19安装yasm(http://www.tortall.net/projects/yasm/releases/)wgethttp://www.tortall.net/projects/yasm/releases/yasm-1.3.0.......
  • Loj 507 接竹竿 题解
    Loj链接:接竹竿${\scr\color{SkyBlue}{\text{Solution}}}$题目大意:给定一个数组,每次加入一种颜色的数,可以取走与它颜色相同的两个数之间的所有数,问最后取走的所有数......
  • 2023牛客寒假算法基础集训营1-大部分题解
    比赛概况solve:ACDHKLMrank:374/3835dirt:630补题情况EFG题解E:鸡算几何题目链接:https://ac.nowcoder.com/acm/contest/46800/E思路:简单的计算几何叉积运算。我......
  • AT_abc139f 题解
    我们注意向量加法的几何意义。将多个向量向加时,最优的情况是所有边的极坐标单调。但是有一种特殊情况,就是从极角最大的到极角最小的。因此把所有向量极角排序,在做一些处......
  • luogu P1452 题解
    管理备注:虽然此题解为乱搞,但是本乱搞是非常有意义的经典乱搞,故保留在题解区中供学习与参考。我们充分发扬人类智慧:将所有点全部绕原点旋转同一个角度,然后按\(x\)坐标......
  • luogu P8207 题解
    在暴力建边的情况下可以kruskal求生成树。但是这样是\(O(n^2)\)的。因为\(lcm(x,y)=x\timesy/\gcd(x,y)\)。所以\(\gcd(x,y)\)越大我们的答案越优。但是......
  • CF1768C 题解
    考虑构造。首先第一轮构造我们把第一次出现的数放到\(p\)里面,第二次出现的放到\(q\)里面。如果有数第三次出现呢?那么显然无解。那么现在\(p\)和\(q\)中都填了一......
  • 题解 P2480 [SDOI2010]古代猪文
    题意求\[g^{\sum\limits_{d|n}C_n^d}\bmod999911659\]\(n,g\le10^9\)一道非常好的数论题,用到了基本所有的基础数论知识。需要使用到的数论知识欧拉定理......