CodeForces 57C Array 组合计数+逆元

题目链接:

http://codeforces.com/problemset/problem/57/C

题意:

给你一个数n,表示有n个数的序列,每个数范围为[1,n],叫你求所有非降和非升序列的个数。

题解:

由于对称性,我们只要求非降序的个数就可以了(n个数全部相等的情况既属于非升也属于非降)

我们在满足条件的n个数之前加一个虚节点1,在第n个数之后加一个n,那么考虑这n+2个数组成的非降序列:

假设序列里的第i个数为a[i],我们设xi=a[i+1]-a[i]+1,1<=i<=n+1,则满足每个数>=1,且sum(x[1],x[2]...x[n+1])=2*n;

那么相当于求将2*n分成n个部分,且每个部分的值大于等于1,则易得非降序列总数为:C(n,2*n-1)(2*n-1 选 n)

所以最后的答案是2*C(n,2*n-1)-n;

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5
 6 const int mod = 1000000007;
 7 typedef long long LL;
 8 int n;
 9 //扩展欧几里得
10 void gcd(int a, int b, int &d, int &x, int &y) {
11     if (!b) { d = a; x = 1; y = 0; }
12     else { gcd(b, a%b, d, y, x); y -= x*(a / b); }
13 }
14 //求逆元
15 int inv(int a) {
16     int d, x, y;
17     gcd(a, mod, d, x, y);
18     return x;
19 }
20 //求阶乘
21 int solve(int _n,int x) {
22     LL ret = 1;
23     while (_n--) {
24         ret *= x;
25         ret %= mod;
26         x--;
27     }
28     return ret;
29 }
30
31 int main() {
32     while (scanf("%d", &n) == 1 && n) {
33         int ans = (LL)solve(n, 2 * n - 1)*inv(solve(n,n))%mod;
34         ans = ans * 2 - n;
35         ans = (ans%mod + mod) % mod;
36         printf("%d\n", ans);
37     }
38     return 0;
39 }
时间: 2024-12-05 15:30:55

CodeForces 57C Array 组合计数+逆元的相关文章

Codeforces 57C Array dp暴力找规律

题目链接:点击打开链接 先是计算非递增的方案, 若非递增的方案数为x, 则非递减的方案数也是x 答案就是 2*x - n 只需求得x即可. 可以先写个n3的dp,然后发现规律是 C(n-1, 2*n-1) 然后套个逆元即可. #include<iostream> #include<cstdio> #include<vector> #include<string.h> using namespace std; #define ll long long #def

Codeforces 57C Array dp暴力找到规律

主题链接:点击打开链接 的非增量程序首先,计算, 如果不增加的节目数量x, 非减少一些方案是x 答案就是 2*x - n 仅仅需求得x就可以. 能够先写个n3的dp,然后发现规律是 C(n-1, 2*n-1) 然后套个逆元就可以. #include<iostream> #include<cstdio> #include<vector> #include<string.h> using namespace std; #define ll long long #

Yue Fei&#39;s Battle(组合计数递推)

//求一个直径为 k 的树有多少种形态,每个点的度不超过 3 // 非常完美的分析,学到了,就是要细细推,并且写的时候要细心 还有除法取模需要用逆元 #include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> using namespace std; #define MOD 1000000007 #define L

bzoj 1004 Cards 组合计数

这道题考察的是组合计数(用Burnside,当然也可以认为是Polya的变形,毕竟Polya是Burnside推导出来的). 这一类问题的本质是计算置换群(A,P)中不动点个数!(所谓不动点,是一个二元组(a,p),a∈A,p∈P ,使得p(a)=a,即a在置换p的作用后还是a). Polya定理其实就是告诉了我们一类问题的不动点数的计算方法. 对于Burnside定理的考察,我见过的有以下几种形式(但归根结底还是计算不动点数): 1.限制a(a∈A)的特点,本题即是如此(限制了各颜色个数,可以

[ZJOI2010]排列计数 (组合计数/dp)

[ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大,只能输出模P以后的值 输入输出格式 输入格式: 输入文件的第一行包含两个整数 n和p,含义如上所述. 输出格式: 输出文件中仅包含一个整数,表示计算1,2,?, 的排列中, Magic排列的个数模 p的值. 输入输出样例 输入样例#1: 20 23 输出样例#1: 16 说明

POJ 1496 POJ 1850 组合计数

Code Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8256 Accepted: 3906 Description Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is t

codeforces A. Array题解

Vitaly has an array of n distinct integers. Vitaly wants to divide this array into three non-empty sets so as the following conditions hold: The product of all numbers in the first set is less than zero (?<?0). The product of all numbers in the secon

POJ 3252 组合计数

Round Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9149 Accepted: 3248 Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro,

HDU4675-GCD of Sequence(数论+组合计数)

GCD of Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 949    Accepted Submission(s): 284 Problem Description Alice is playing a game with Bob. Alice shows N integers a1, a2, -, aN, an