题意

给你\(n\)和\(m\),问满足以下条件的数列的个数:

  • 数列长度为\(n\)
  • 数列值域范围为\(\left[1,m\right]\)
  • 数列有且仅有一对相等的数
  • 数列是单峰数列(先严格递增后严格递减,严格递增或严格递减)

解题思路

首先从\(m\)元素中挑出\(n-1\)个不同的值,有\(C_m^{n-1}\)种方法。现在数列的值域就可以只看成\(\left[1,n-1\right]\)了。

然后这\(n-1\)个元素中,先放置好\(n-1\),假设重复元素的值为\(i(i\in\left[1,n-2\right])\)。那么这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 '\n' 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 = '\0';
return REOF;
} inline bool read_dbl(double &x){
bool f = 0; char ch = nc(); x = 0;
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=nc();}
while(ch>='0'&&ch<='9'){x=x*10.0+(ch^48);ch=nc();}
if(ch == '.') {
double tmp = 1; ch = nc();
while(ch>='0'&&ch<='9'){tmp=tmp/10.0;x=x+tmp*(ch^48);ch=nc();}
}
if(f)x=-x;
return REOF;
} template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<'='<<h<<endl; } template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
while(*sdbg!=',')cerr<<*sdbg++;
cerr<<'='<<h<<','<<' '; _dbg(sdbg+1, a...);
} template<class T> ostream &operator<<(ostream& os, vector<T> V) {
os << "["; for (auto vv : V) os << vv << ","; return os << "]";
} template<class T> ostream &operator<<(ostream& os, set<T> V) {
os << "["; for (auto vv : V) os << vv << ","; return os << "]";
} template<class T> ostream &operator<<(ostream& os, map<T,T> V) {
os << "["; for (auto vv : V) os << vv << ","; return os << "]";
} template<class L, class R> ostream &operator<<(ostream &os, pair<L,R> P) {
return os << "(" << P.st << "," << P.nd << ")";
} #define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
} using namespace IO;
const int maxn=2e5+5;
const int maxv=2e5+5;
const int mod=998244353; // 998244353 1e9+7
const int INF=1e9+7; // 1e9+7 0x3f3f3f3f 0x3f3f3f3f3f3f3f3f
const double eps=1e-12; int dx[4]={0,1,0,-1};
//int dx[8]={1,0,-1,1,-1,1,0,-1};
int dy[4]={1,0,-1,0};
//int dy[8]={1,1,1,0,0,-1,-1,-1}; // #define ls (x<<1)
// #define rs (x<<1|1)
// #define mid ((l+r)>>1)
// #define lson ls,l,mid
// #define rson rs,mid+1,r // int tot,head[maxn];
// struct Edge{
// int v,nxt;
// Edge(){}
// Edge(int _v,int _nxt):v(_v),nxt(_nxt){}
// }e[maxn<<1];
// void init(){
// tot=1;
// memset(head,0,sizeof(head));
// }
// void addedge(int u,int v){
// e[tot]=Edge(v,head[u]); head[u]=tot++;
// e[tot]=Edge(u,head[v]); head[v]=tot++;
// }
// void addarc(int u,int v){
// e[tot]=Edge(v,head[u]); head[u]=tot++;
// } /**
* ********** Backlight **********
* 仔细读题
* 注意边界条件
* 记得注释输入流重定向
* 没有思路就试试逆向思维
* 加油,奥利给
*/
ll n,m;
ll qp(ll a,ll b){
ll res=1;
while(b){
if(b&1)res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
} ll inv(ll x){return qp(x,mod-2);} void solve(){
read(n,m);
ll ans=n-2;
for(int i=1;i<=m;i++)ans=ans*i%mod;
for(int i=1;i<=n-1;i++)ans=ans*inv(i)%mod;
for(int i=1;i<=m-n+1;i++)ans=ans*inv(i)%mod;
ans=ans*qp(2,n-2)%mod;
ans=ans*inv(2)%mod;
printf("%lld\n",ans);
} int main()
{
// freopen("in.txt","r",stdin);
// ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
// int _T; read(_T); for(int _=1;_<=_T;_++)solve();
// while(read(n))solve();
solve();
return 0;
}

Codeforces1312D Count the Arrays 组合数学的更多相关文章

  1. D. Count the Arrays 计数题

    D. Count the Arrays 也是一个计数题. 题目大意: 要求构造一个满足题意的数列. \(n\) 代表数列的长度 数列元素的范围 \([1,m]\) 数列必须有且仅有一对相同的数 存在一 ...

  2. Codeforces Round #258 (Div. 2) D. Count Good Substrings —— 组合数学

    题目链接:http://codeforces.com/problemset/problem/451/D D. Count Good Substrings time limit per test 2 s ...

  3. HDU 4372 Count the Buildings 组合数学

    题意:有n个点上可能有楼房,从前面可以看到x栋楼,从后面可以看到y栋,问楼的位置有多少种可能. 印象中好像做过这个题,

  4. Educational Codeforces Round 83 D. Count the Arrays(组合,逆元,快速幂)

    题意: 从 m 个数中选 n - 1 个数组成先增后减的长为 n 的数组. 思路: 因为 n 个数中有两个数相同,所以每种情况实际上只有 n - 1 个不同的数--$c_m^{n - 1}$, 除去最 ...

  5. [程序设计语言]-[核心概念]-02:名字、作用域和约束(Bindings)

    本系列导航 本系列其他文章目录请戳这里. 1.名字.约束时间(Binding Time) 在本篇博文开始前先介绍两个约定:第一个是“对象”,除非在介绍面向对象语言时,本系列中出现的对象均是指任何可以有 ...

  6. 305. Number of Islands II

    题目: A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand  ...

  7. java.util.AbstractStringBuilder源码分析

    AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大 ...

  8. Java数据结构和算法总结-字符串及高频面试题算法

    前言:周末闲来无事,在七月在线上看了看字符串相关算法的讲解视频,收货颇丰,跟着视频讲解简单做了一下笔记,方便以后翻阅复习同时也很乐意分享给大家.什么字符串在算法中有多重要之类的大路边上的客套话就不多说 ...

  9. LeetCode第七天

    ==数组 Medium== 40.(162)Find Peak Element JAVA //斜率思想,二分法 class Solution { public int findPeakElement( ...

随机推荐

  1. 一文说通C#中的异步编程补遗

    前文写了关于C#中的异步编程.后台有无数人在讨论,很多人把异步和多线程混了. 文章在这儿:一文说通C#中的异步编程 所以,本文从体系的角度,再写一下这个异步编程.   一.C#中的异步编程演变 1. ...

  2. Azure DevOps+Docker+Asp.NET Core 实现CI/CD(一 .简介与创建自己的代理池)

    前言 本文主要是讲解如何使用Azure DevOps+Docker 来实现持续集成Asp.NET Core项目(当然 也可以是任意项目). 打算用三个篇幅来记录完整的全过程 觉得有帮助的朋友~可以左上 ...

  3. 5个Python特性 越早知道越好的

    Kirill Sharkovski 发布在 Unsplash 杂志上的照片 AI开发者按,Python 是近十年来兴起的编程语言,并且被证明是一种非常强大的语言.我用 Python 构建了很多应用程序 ...

  4. javascript Math对象 、Date对象笔记

    Math对象     Math 是一个内置对象, 它具有数学常数和函数的属性和方法.不是一个函数对象.     Math数学对象不是构造函数使用的时候不需要new来调用,可以直接使用里面的属性和方法 ...

  5. css实现折扇效果

    总结思路: 1.首先进行结构的书写   <div class="box"></div> 2.要进行图片的重叠要用到position定位,需要重叠的元素及子元 ...

  6. java循环语句for与无限循环

    一 for循环 for循环语句是最常用的循环语句,一般用在循环次数已知的情况下. 格式: for(初始化表达式; 循环条件; 操作表达式){ 执行语句 ……… } 循环流程: for(① ; ② ; ...

  7. C#算法设计排序篇之03-直接插入排序(附带动画演示程序)

    直接插入排序(Straight Insertion Sort) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/679 访 ...

  8. C#LeetCode刷题之#884-两句话中的不常见单词(Uncommon Words from Two Sentences)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3816 访问. 给定两个句子 A 和 B . (句子是一串由空格分 ...

  9. Java学习书籍与社区

    编码规范:<阿里巴巴Java开发手册> 技术架构:<大型网站技术架构核心原理与案例分析>---李智慧 Spring架构与设计原理解析:<Spring技术内幕深入解析Spr ...

  10. do...while循环语句(水仙花)

    #define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>#include<stdlib.h&g ...