zoj——3557 How Many Sets II

How Many Sets II


Time Limit: 2 Seconds      Memory Limit: 65536 KB


Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition:

  • T is a subset of S
  • |T| = m
  • T does not contain continuous numbers, that is to say x and x+1 can not both in T

Input

There are multiple cases, each contains 3 integers n ( 1 <= n <= 109 ), m ( 0 <= m <= 104m <= n ) and p ( p is prime, 1 <= p <= 109 ) in one line seperated by a single space, proceed to the end of file.

Output

Output the total number mod p.

Sample Input

5 1 11
5 2 11

Sample Output

5
6

题目大意:
给一个集合,一共n个元素,从中选取m个元素,满足选出的元素中没有相邻的元素,一共有多少种选法(结果对p取模1 <= p <= 10^9) 
思路:好像是裸题、、、、
用插板法求出组合数。既然是从n个数中选择m个数,那么剩下的数为n-m,那么可以产生n-m+1个空,这道题就变成了把m个数插到这n-m+1个空中有多少种方法,即C(n-m+1,m)%p
但是求乘法逆元的已经行不通了,因为这里我们不确定他给出的p是否为素数,这样我们就只能用卢卡斯定理了卢卡斯定理不会的转:http://www.cnblogs.com/L-Memory/p/7352397.html不要预处理了,因为我们这里p不知道,而且如果要处理的话就要开10^9*long long空间。代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll t,n,m,p,ans;
ll read()
{
    ll x=0,f=1; char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
ll qpow(ll n,ll k,ll q)
{
    ll res=1;
    while(k)
    {
        if(k&1) res=res*n%p;
        n=n*n%p; k>>=1;
    }return res;
}
ll c(ll n,ll m,ll p)
{
    ll n1=1,m1=1;
    if(m>n) return 0;
    for(int i=1;i<=m;i++)
     m1=m1*i%p;
    for(int i=n-m+1;i<=n;i++)
     n1=n1*i%p;
    return n1*qpow(m1,p-2,p)%p;
}
ll lus(ll n,ll m,ll p)
{
    if(m==0) return 1;
    return c(n%p,m%p,p)*lus(n/p,m/p,p)%p;
}
int main()
{
    while(scanf("%lld%lld%lld",&n,&m,&p)!=EOF)
    {
        ans=lus(n-m+1,m,p);
        printf("%lld\n",ans);
    }
    return 0;
}

 
时间: 2024-10-24 00:30:56

zoj——3557 How Many Sets II的相关文章

zoj 3557 How Many Sets II

How Many Sets II Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition: T is a subset of S |T| = m T does not contain continuous numbers

ZOJ 3557 How Many Sets II lucas 定理

插空法 大组合数取余 #include <cstdio> #include <cstring> using namespace std; typedef long long LL; //求整数x和y,使得ax+by=d, 且|x|+|y|最小.其中d=gcd(a,b) void gcd(LL a, LL b, LL& d, LL& x, LL& y) { if(!b) { d = a; x = 1; y = 0; } else { gcd(b, a%b, d

ZOJ 3557-How Many Sets II(Lucas定理+插板法求组合数)

题目地址:ZOJ 3557 题意:给一个集合,一共n个元素,从中选取m个元素,满足选出的元素中没有相邻的元素,一共有多少种选法(结果对p取模1 <= p <= 10^9) 思路:用插板法求出组合数.既然是从n个数中选择m个数,那么剩下的数为n-m,那么可以产生n-m+1个空,这道题就变成了把m个数插到这n-m+1个空中有多少种方法,即C(n-m+1,m)%p.然后就Lucas定理上去乱搞.因为这道题的p较大,所以不能预处理. #include <stdio.h> #include

ZOJ3557 How Many Sets II( Lucas定理)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud How Many Sets II Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition: T is

[容斥原理] zoj 3556 How Many Sets I

主题链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do? problemId=4535 How Many Sets I Time Limit: 2 Seconds      Memory Limit: 65536 KB Give a set S, |S| = n, then how many ordered set group (S1, S2, ..., Sk) satisfies S1 ∩ S2 ∩ ... ∩ Sk = ?. (Si is

Decidability and R.E. Sets (II)

1. Listing Theorem A non-empty set is r.e. iff it is the range of a unary total computable funciton. That means the elements of a r.e. set can be effectively generated. We can also prove that a set is r.e. iff it is the range of a computable function

ZOJ 2688 The Review Plan II

https://zoj.pintia.cn/problem-sets/91827364500/problems/91827369470 题意: n天n个计划,一天完成一个计划,第i个计划不能在第i天和第i+1天完成,第n个计划不能在第n天和第1天完成,求安排计划的方案数. 有禁区的排列问题 在n*n有禁区棋盘上放n个棋子,每行每列只能放1个,第i行的禁区为第i和i+1列,第n行禁区为第n和1列 根据容斥原理,得 方案数=n! - r1(n-1)! + r2(n-2)! - …… ± rn 其中r

Zoj 3535 Gao the String II (AC自己主动机+dp)

题目大意: 用集合A中的串构造出一个串,使之让很多其它的setB中的串成为他的子串. 思路分析: 和 Codeforces 86C 几乎相同. 只是这里是要用A中的构造. 先用A 和 B的串构造一个自己主动机.然后对于A集合的尾结点给出一个最大后缀匹配,对于B集合的尾结点给一个权值. dp[i][j][k] 表示已经构造出来了一个长度为i的串,如今走到了自己主动机的j结点.i长度后面有k个字符是没有匹配到的. 继续在自己主动机上走进行状态转移. if(isword >= k +1 )dp [i+

Zoj 3535 Gao the String II (AC自动机+dp)

题目大意: 用集合A中的串构造出一个串,使之让更多的setB中的串成为他的子串. 思路分析: 和 Codeforces 86C 差不多. 不过这里是要用A中的构造. 先用A 和 B的串构造一个自动机.然后对于A集合的尾结点给出一个最大后缀匹配,对于B集合的尾结点给一个权值. dp[i][j][k] 表示已经构造出来了一个长度为i的串,现在走到了自动机的j结点,i长度后面有k个字符是没有匹配到的. 继续在自动机上走进行状态转移. if(isword >= k +1 )dp [i+1] [j->n