首页 > 其他分享 >CodeForces 1747E List Generation

CodeForces 1747E List Generation

时间:2022-11-06 13:11:28浏览次数:91  
标签:dbinom limits Generation ll List CodeForces long int mod

CF 传送门

洛谷传送门

考虑将问题抽象成:左上角为 \((0,0)\)、右下角为 \((n,m)\) 的网格图,求所有满足至少有一条 只向下或向右走的路径 经过点集内所有点的的不同的点集大小之和。

显然对于一个合法的点集,经过它的路径可能不止一条,去重也很麻烦。考虑钦定两个点间的访问顺序,比如先向下再向右走,这样对于每个合法的点集,都有且仅有一条经过它的路径。

将路径的 拐点 分为两类:先向右再向下和先向下再向右。如下图,红色点表示第一类拐点,蓝色点表示第二类拐点。

考虑 枚举先向右再向下的拐点个数 ,设有 \(i\) 个。选择拐点的方案为 \(\dbinom{n}{i}\dbinom{m}{i}\)(纵坐标范围 \([0,n-1]\),横坐标范围 \([1,m]\))。这样就唯一确定了一条路径。路径上还有 \(s=n+m-i-1\) 个点,这 \(i\) 个点可以任选,总贡献为 \(\sum\limits_{j=0}^s \dbinom{s}{j}(i+2+j) = (i+2)2^s + \sum\limits_{j=0}^s \dbinom{s}{j}j\)。

考虑 \(\sum\limits_{j=0}^s \dbinom{s}{j}j\) 这部分如何快速计算。注意到 \(\sum\limits_{j=0}^s \dbinom{s}{j}j = \sum\limits_{j=0}^s \dbinom{s}{j}(s-j)\),相加再除以 \(2\) 后得原式 \(= s2^{s-1}\)。

code
/*

p_b_p_b txdy
AThousandSuns txdy
Wu_Ren txdy
Appleblue17 txdy

*/

#include <bits/stdc++.h>
#define pb push_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 10000100;
const int N = 10000000;
const ll mod = 1000000007;

ll qpow(ll b, ll p) {
	ll res = 1;
	while (p) {
		if (p & 1) {
			res = res * b % mod;
		}
		b = b * b % mod;
		p >>= 1;
	}
	return res;
}

ll n, m, fac[maxn], ifac[maxn], pw[maxn];

void init() {
	fac[0] = pw[0] = 1;
	for (int i = 1; i <= N; ++i) {
		fac[i] = fac[i - 1] * i % mod;
		pw[i] = pw[i - 1] * 2 % mod;
	}
	ifac[N] = qpow(fac[N], mod - 2);
	for (int i = N - 1; ~i; --i) {
		ifac[i] = ifac[i + 1] * (i + 1) % mod;
	}
}

inline ll C(ll n, ll m) {
	if (n < m || n < 0 || m < 0) {
		return 0;
	} else {
		return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
	}
}

void solve() {
	scanf("%lld%lld", &n, &m);
	ll ans = 0;
	for (ll i = 0; i <= min(n, m); ++i) {
		int s = n + m - i - 1;
		ans = (ans + C(n, i) * C(m, i) % mod * (pw[s] * (i + 2) % mod + (s - 1 >= 0 ? s * pw[s - 1] % mod : 0)) % mod) % mod;
	}
	printf("%lld\n", ans);
}

int main() {
	init();
	int T = 1;
	scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:dbinom,limits,Generation,ll,List,CodeForces,long,int,mod
From: https://www.cnblogs.com/zltzlt-blog/p/16862436.html

相关文章

  • replace() 数学 数学 动规 List<int[]> 数学 二分
    1678.设计Goal解析器returncommand.replace("()","o").replace("(al)","al");888.公平的糖果交换766.托普利茨矩阵只需判断:前行中除最后一个元素外剩余的元......
  • ArrayList源码分析
    目标:理解ArrayList的底层数据结构深入掌握ArrayList查询快,增删慢的原因掌握ArrayList的扩容机制掌握ArrayList初始化容量过程掌握ArrayList出现线程安全问题原因及解......
  • Educational Codeforces Round 138 E,F
    E一道比较基础的题。首先就是纵向,走无障碍的格子,无法四联通和横向,走有障碍的格子,八联通是等价的。也就是,如果我们要让其不存在非法路径,那么应该存在一个从第一列出发,一......
  • Educational Codeforces Round 118 D
    D.MEXSequences对于一个数x要是前面出现过0,1,2...x-1我们显然可以将他放在后面要是前面出现过012...x-1x我们也可以将他放在后面但是观察样例还有一种情况......
  • java常用API--->ArryList集合基础
    简述集合和数组的对比数组长度固定,集合长度可变。数组可存储基本数据类型和引用数据类型,集合只能存储引用数据类型,如果要存储基本数据类型要将其变成包装类Arrylis......
  • Codeforces Round #826 (Div. 3) D. Masha and a Beautiful Tree(树+dfs)
    D.MashaandaBeautifulTree题目大意:给定一颗满二叉树的叶子节点,让我们更换子树位置,从而让叶子节点排序为升序求最小操作数,如果不能移动成那样的话,直接输出-1.in......
  • List泛型数组 Dictionary字典
    泛型数组usingSystem.Collections.Generic;为了解决动态数组的拆装箱问题,故引入泛型数组。//创建一个int类型的泛型数组List<int>list=newList<int>();//数据......
  • Codeforces 杂题记录
    CF1753A2(调整、贪心)考虑钦定\([1,n]\)分成一段,调整就是把贡献取相反数。CF1753B每次把\((i+1)\)和\(i!\)合并成一个\((i+1)!\),看能不能合并到\(x!\)。CF1753C(......
  • Codeforces Round #832 (Div. 2) C. Swap Game (博弈论)
    https://codeforces.com/contest/1747/problem/CC.SwapGame题目大意:给定一个长度为n的数组a,每次只要当我想动但是发现a[1]==0的时候我就输了要么就是我每次把a[1]......
  • 「题解」Codeforces 1612F Armor and Weapons
    首先可以不管套件,假定\(n<m\),那么答案不超过\(\mathcal{O}(\logn+\frac{m}{n})\),也就是先倍增把\(n\)造出来,然后一步步造\(m\).答案这么小,那么常见的套路就是把答案......