zoukankan      html  css  js  c++  java
  • BZOJ2142: 礼物

    2142: 礼物

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 2169  Solved: 956
    [Submit][Status][Discuss]

    Description

    一年一度的圣诞节快要来到了。每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物。不同的人物在小E
    心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多。小E从商店中购买了n件礼物,打算送给m个人
    ,其中送给第i个人礼物数量为wi。请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某
    个人在这两种方案中收到的礼物不同)。由于方案数可能会很大,你只需要输出模P后的结果。

    Input

    输入的第一行包含一个正整数P,表示模;
    第二行包含两个整整数n和m,分别表示小E从商店购买的礼物数和接受礼物的人数;
    以下m行每行仅包含一个正整数wi,表示小E要送给第i个人的礼物数量。

    Output

    若不存在可行方案,则输出“Impossible”,否则输出一个整数,表示模P后的方案数。

    Sample Input

    100
    4 2
    1
    2

    Sample Output

    12
    【样例说明】
    下面是对样例1的说明。
    以“/”分割,“/”前后分别表示送给第一个人和第二个人的礼物编号。12种方案详情如下:
    1/23 1/24 1/34
    2/13 2/14 2/34
    3/12 3/14 3/24
    4/12 4/13 4/23
    【数据规模和约定】
    设P=p1^c1 * p2^c2 * p3^c3 * … *pt ^ ct,pi为质数。
    对于100%的数据,1≤n≤109,1≤m≤5,1≤pi^ci≤10^5。

    HINT

    Source

    【题解】

    裸的exlucas

    脑抽每次都暴力分解p。。。完全可以分解一次根号p的

    公式: 

    $inom n {w_1}+inom {n-w_1} {w_2}+inom {n-w_1-w_2} {w_3}+cdots$

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <queue>
      7 #include <vector>
      8 #include <map>
      9 #include <string> 
     10 #include <cmath> 
     11 #include <sstream>
     12 #define min(a, b) ((a) < (b) ? (a) : (b))
     13 #define max(a, b) ((a) > (b) ? (a) : (b))
     14 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
     15 template<class T>
     16 inline void swap(T &a, T &b)
     17 {
     18     T tmp = a;a = b;b = tmp;
     19 }
     20 inline void read(long long &x)
     21 {
     22     x = 0;char ch = getchar(), c = ch;
     23     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     24     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     25     if(c == '-') x = -x;
     26 }
     27 const long long INF = 0x3f3f3f3f;
     28 long long pow(long long a, long long b, long long mod)
     29 {
     30     long long r = 1, base = a % mod;
     31     for(;b;b >>= 1)
     32     {
     33         if(b & 1) r *= base, r %= mod;
     34         base *= base, base %= mod;
     35     }
     36     return r;
     37 }
     38 void exgcd(long long a, long long b, long long &x, long long &y)
     39 {
     40     if(!b) x = 1, y = 0;
     41     else exgcd(b, a % b, y, x), y -= (a / b) * x;
     42 }
     43 long long ni(long long x, long long mod)
     44 {
     45     long long a,b;exgcd(x, mod, a, b);
     46     a = (a % mod + mod) % mod;
     47     return !a ? mod : a;
     48 }
     49 long long calc(long long n, long long p, long long pt)
     50 {
     51     if(!n) return 1;long long ans = 1;
     52     for(long long i = 1;i <= pt;++ i) if(i % p) ans *= i, ans %= pt;
     53     ans = pow(ans, n/pt, pt);
     54     for(long long i = n%pt;i >= 1;-- i) if(i % p) ans *= i, ans %= pt;
     55     return ans * calc(n/p, p, pt) % pt;
     56 }
     57 long long C(long long n, long long m, long long p, long long pt)
     58 {
     59     if(n < m || n < 0 || m < 0) return 0;
     60     long long cnt = 0;
     61     for(long long i = n;i;i /= p) cnt += i/p;
     62     for(long long i = m;i;i /= p) cnt -= i/p;
     63     for(long long i = n - m;i;i /= p) cnt -= i/p;
     64     return pow(p, cnt, pt) * calc(n, p, pt) % pt * ni(calc(m, p, pt), pt) % pt * ni(calc(n - m, p, pt), pt) % pt;
     65 } 
     66 long long prime[100000], cnt[100000], fang[100000], tot;
     67 void fenjie(long long p)
     68 {
     69     long long tmp = sqrt(p),tmp2 = p;
     70     for(long long i = 2;i <= tmp;++ i)
     71         if(tmp2 % i == 0)
     72         {
     73             prime[++ tot] = i, fang[tot] = 1;
     74             while(tmp2 % i == 0) ++ cnt[tot], tmp2 /= i, fang[tot] *= i;
     75         }
     76     if(tmp2 > 1) prime[++ tot] = tmp2, cnt[tot] = 1, fang[tot] = tmp2;
     77 }
     78 long long exlucas(long long n, long long m, long long mod)
     79 {
     80     long long ans = 0;
     81     for(long long i = 1;i <= tot;++ i)
     82     {
     83         long long pt = fang[i];
     84         long long tmp3 = C(n, m, prime[i], pt);
     85         ans += tmp3 * (mod/pt) % mod * ni(mod/pt, pt) % mod;
     86         ans %= mod;
     87     }
     88     return ans;
     89 }
     90 long long n,m,w,p,ans = 1;
     91 int main()
     92 {
     93     read(p), read(n), read(m);fenjie(p);
     94     for(long long i = 1;i <= m;++ i) 
     95     {    
     96         read(w);
     97         if(n - w < 0)
     98         {
     99             printf("Impossible");
    100             return 0;
    101         }
    102         ans *= exlucas(n,w,p), n -= w;
    103         ans %= p;
    104     }
    105     printf("%lld", ans);
    106     return 0;
    107 }
    BZOJ2142
  • 相关阅读:
    hdu 1269 迷宫城堡 (并查集)
    hdu 1272 小希的迷宫 (深搜)
    hdu 1026 Ignatius and the Princess I (深搜)
    hdu 1099 Lottery
    hdu 1068 Girls and Boys (二分匹配)
    几个基础数位DP(hdu 2089,hdu 3555,uestc 1307 windy 数)
    hdu 1072 Nightmare (广搜)
    hdu 1398 Square Coins (母函数)
    hdu 1253 胜利大逃亡 (深搜)
    hdu 1115 Lifting the Stone (求重心)
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8407119.html
Copyright © 2011-2022 走看看