zoukankan      html  css  js  c++  java
  • bzoj 4338[BJOI2015] 糖果

    4338: BJOI2015 糖果

    Time Limit: 2 Sec  Memory Limit: 256 MB

    Description

    Alice 正在教她的弟弟 Bob 学数学。 
    每天,Alice 画一个N行M 列的表格,要求 Bob在格子里填数。 
    Bob已经学会了自然数1到K的写法。因此他在每个格子里填1 ~ K之间的整数。 
    Alice 告诉 Bob,如果 Bob 填写完表格的 N*M 个数以后,每行的数从第 1 列到第 M
    列单调不减,并且任意两行至少有一列的数不同,而且以前 Bob 没有填写过相同的表格,
    那么Alice 就给Bob吃一颗糖果。 
    Bob想知道,如果每天填写一遍表格,最多能吃到多少颗糖果。 
    答案模P输出。 

    Input

    第一行,四个整数依次是N, M, K, P。 

    Output

    输出一行,一个整数,表示答案模P 后的结果。 

    Sample Input

    【样例输入1】
    1 3 3 10
    【样例输入2】
    2 2 2 10

    Sample Output

    【样例输出1】
    0
    【样例输出2】
    6

    HINT

    【样例解释】 

    样例1。表格只有一行。每个格子可以填写1 ~ 3。有10种填写方法,依次为1 1 1,

    1 1 2,1 1 3,1 2 2,1 2 3,1 3 3,2 2 2,2 2 3,2 3 3,3 3 3。   

    样例2。表格有两行。有6 种填写方法,依次为  1 1/1 2, 1 1/2 2, 1 2/1 1, 1 2/2 

    2, 2 2/1 1, 2 2/1 2。 

    【数据规模与约定】 

    100% 的数据中,1 ≤ N, M ≤ 10^5,1 ≤ P, K ≤ 2*10^9. 
     
    公式很好写出来
    先算出来一行 M 列 填 K 单调不减个数的方法数
     即 x1 + x2 + ... xk = M    (xi >= 0)
    方案数 为  sum = $C_{M + K - 1} ^ {K - 1}$ = $C_{M + K - 1} ^ {M}$
    每行方案不同
    总的方案就是  $A_{sum} ^ N$
    我们发现 M 不大, 所以可以除数的所有质因子都提出来,然后用分子上的数去除,剩下的就是答案。
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define LL long long
      6 
      7 using namespace std;
      8 
      9 int N, M, K, P;
     10 
     11 const int MAXM = 1e5 + 10;
     12 
     13 int cnt = 0;
     14 int prime[MAXM];
     15 LL val[MAXM];
     16 int num[MAXM];
     17 int f[MAXM];
     18 
     19 inline LL read()
     20 {
     21     LL x = 0, w = 1; char ch = 0;
     22     while(ch < '0' || ch > '9') {
     23         if(ch == '-') {
     24             w = -1;
     25         }
     26         ch = getchar();
     27     }
     28     while(ch >= '0' && ch <= '9') {
     29         x = x * 10 + ch - '0';
     30         ch = getchar();
     31     }
     32     return x * w;
     33 }
     34 
     35 void init()
     36 {
     37     for(int i = 2; i < MAXM; i++) {
     38         if(!f[i]) {
     39             f[i] = i;
     40             prime[++cnt] = i;
     41         } 
     42         for(int j = 1; j <= cnt && i * prime[j] < MAXM; j++) {
     43             f[i * prime[j]] = prime[j];
     44             if(i % prime[j] == 0) {
     45                 break;
     46             }
     47         }    
     48     }
     49     /*for(int i = 0; i <= 2000; i++) {
     50         c[i][0] = 1;
     51         for(int j = 1; j <= i; j++) {
     52             c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % P;
     53         }
     54     }*/
     55 }
     56 
     57 int main()
     58 {
     59     N = read(), M = read(), K = read(), P = read();
     60     init();
     61     for(int j = 0; j < M; j++) {
     62         val[j] = K + j;
     63     }
     64     for(int j = M; j > 1; j--) {
     65         int t = j;
     66         while(t > 1) {
     67             num[f[t]]++;
     68             t = t / f[t];
     69         }
     70     }
     71     int st = K;
     72     for(int i = 1; i <= cnt; i++) {
     73         for(int j = ((st - 1) / prime[i] + 1) * prime[i]; j < K + M; j += prime[i]) {
     74             int t = j - st;
     75             //cout<<prime[i]<<" "<<j<<" "<<val[t]<<" "<<num[prime[i]]<<endl;
     76             while(val[t] % prime[i] == 0 && num[prime[i]]) {
     77                 val[t] /= prime[i];
     78                 num[prime[i]]--;
     79             }
     80             if(num[prime[i]] == 0) {
     81                 break;
     82             }
     83         }
     84     }
     85     LL ans = 1;
     86     for(int i = 0; i < M; i++) {
     87         ans = ans * val[i] % P;
     88     }
     89     //cout<<ans<<" "<<c[M + K - 1][K - 1] % P<<endl; 
     90     LL now = ans;
     91     for(int i = 1; i < N; i++) {
     92         ans = ans * (now - i) % P;
     93     }
     94     printf("%lld
    ", ans);
     95     return 0;
     96 }
     97 
     98 /*
     99 
    100 100 10 5 1000000000
    101 
    102 
    103 */
    View Code
  • 相关阅读:
    PHP流程控制之do...while循环的区别
    php流程控制 之循环语句的使用
    PHP流程控制之分支结构switch语句的使用
    PHP流程控制之if语句多种嵌套
    PHP流程控制之嵌套if...else...elseif结构
    PHP基础语法之 三元运算符和其它运算符
    PHP基础语法之 位运算
    php常量和变量之变量引用
    php数据类型之自动转换和强制转换
    php数据类型之查看和判断数据类型
  • 原文地址:https://www.cnblogs.com/wuenze/p/8598153.html
Copyright © 2011-2022 走看看