Codeforces1312D Count the Arrays 组合数学
Posted zengzk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces1312D Count the Arrays 组合数学相关的知识,希望对你有一定的参考价值。
题意
给你(n)和(m),问满足以下条件的数列的个数:
- 数列长度为(n)
- 数列值域范围为(left[1,m ight])
- 数列有且仅有一对相等的数
- 数列是单峰数列(先严格递增后严格递减,严格递增或严格递减)
解题思路
首先从(m)元素中挑出(n-1)个不同的值,有(C_m^{n-1})种方法。现在数列的值域就可以只看成(left[1,n-1 ight])了。
然后这(n-1)个元素中,先放置好(n-1),假设重复元素的值为(i(iinleft[1,n-2
ight]))。那么这3个元素的位置只有一种放置方法符合条件。还剩下(n-3)个元素,这些元素既可以在峰的左侧,也可以在峰的右侧,且对于所有分法都有且只有一种放置方法,所以有(2^{n-3})种方法。最后乘上(i)的取值方法数也就是(n-2),结果如下:
[
Ans=(n-2)C_m^{n-1}2^{n-3}
]
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
#define x first
#define y second
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define endl '
'
const double PI=acos(-1.0);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int l,int r){return l+rng()%(r-l+1);}
namespace IO{
bool REOF = 1; //为0表示文件结尾
inline char nc() {
static char buf[100000], *p1 = buf, *p2 = buf;
return p1 == p2 && REOF && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? (REOF = 0, EOF) : *p1++;
}
template<class T>
inline bool read(T &x) {
char c = nc();bool f = 0; x = 0;
while (c<'0' || c>'9')c == '-' && (f = 1), c = nc();
while (c >= '0'&&c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = nc();
if(f)x=-x;
return REOF;
}
template<typename T, typename... T2>
inline bool read(T &x, T2 &... rest) {
read(x);
return read(rest...);
}
inline bool need(char &c) { return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')); }
// inline bool need(char &c) { return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')) || c==' '; }
inline bool read_str(char *a) {
while ((*a = nc()) && need(*a) && REOF)++a; *a = '