传送门


证明自己学过exLucas

这题计算的是本质不相同的排列数量,不难得到答案是\(\frac{n!}{\prod\limits_{i=1}^m w_i! \times (n - \sum\limits_{i=1}^m w_i)!}\)

但是模数不一定是质数,于是用exLucas计算即可。

#include<bits/stdc++.h>
#define int long long
//This code is written by Itst
using namespace std;

int peo[7] , ans[10][2];
int cnt , N , M , P;

inline int poww(int a , int b , int mod = 1e15){
    int times = 1;
    while(b){
        if(b & 1)
            times = times * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return times;
}

void exgcd(int a , int b , int &x , int &y){
    !b ? (x = 1 , y = 0) : (exgcd(b , a % b , y , x) , y -= a / b * x);
}

inline int inv(int a , int b){
    a %= b;
    int x , y;
    exgcd(a , b , x , y);
    return (x + b) % b;
}

int jc(int N , int p , int mod){
    if(!N)
        return 1;
    int times = 1;
    for(int j = 1 ; j < mod ; ++j)
        if(j % p)
            times = times * j % mod;
    times = poww(times , N / mod , mod);
    for(int j = N / mod * mod + 1 ; j <= N ; ++j)
        if(j % p)
            times = times * j % mod;
    return times * jc(N / p , p , mod) % mod;
}

int cntp(int N , int p){
    int sum = 0;
    while(N >= p)
        sum += (N /= p);
    return sum;
}

void calc(int p , int k){
    int mod = poww(p , k) , c = cntp(N , p);
    for(int j = 1 ; j <= M ; ++j)
        c -= cntp(peo[j] , p);
    ans[++cnt][0] = mod;
    if(c < k){
        ans[cnt][1] = poww(p , c) * jc(N , p , mod) % mod;
        for(int j = 1 ; j <= M ; ++j)
            ans[cnt][1] = ans[cnt][1] * inv(jc(peo[j] , p , mod) , mod) % mod;
    }
}

signed main(){
    #ifndef ONLINE_JUDGE
    //freopen("in" , "r" , stdin);
    //freopen("out" , "w" , stdout);
    #endif
    cin >> P >> N >> M;
    for(int i = 1 ; i <= M ; ++i){
        cin >> peo[i];
        peo[M + 1] += peo[i];
    }
    if(peo[M + 1] > N){
        puts("Impossible");
        return 0;
    }
    peo[M + 1] = N - peo[M + 1];
    ++M;
    int tmp = P;
    for(int i = 2 ; i * i <= tmp ; ++i)
        if(tmp % i == 0){
            int cnt = 0;
            while(tmp % i == 0){
                ++cnt;
                tmp /= i;
            }
            calc(i , cnt);
        }
    if(tmp - 1)
        calc(tmp , 1);
    int sum = 0;
    for(int i = 1 ; i <= cnt ; ++i)
        sum = (sum + ans[i][1] * (P / ans[i][0]) % P * inv(P / ans[i][0] , ans[i][0])) % P;
    cout << sum;
    return 0;
}

最新文章

  1. Linux 计划任务
  2. 从零开始搭建架构实施Android项目
  3. 线段树(codevs1082)
  4. java笔记--使用线程池优化多线程编程
  5. 一款点击图片进行无限循环的jquery手风琴特效
  6. UVa 131 - The Psychic Poker Player
  7. docker初步
  8. javascript保留两位
  9. 【bzoj1552】[Cerc2007]robotic sort
  10. Java排序算法之插入排序
  11. HTML笔记04---计时事件
  12. [Swift]LeetCode600. 不含连续1的非负整数 | Non-negative Integers without Consecutive Ones
  13. Java Swing实现展示数据,以及过滤排序
  14. JS 实现版本号比较功能
  15. 解决yum安装mysql时Requires: libc.so.6(GLIBC_2.17)(64bit)
  16. Linux共享库LD_LIBRARY_PATH与ld.so.conf
  17. 【POJ1509】Glass Beads
  18. openstack(pike 版)集群部署(一)----基础环境部署
  19. 10、MySQL 的复制
  20. IE下的Firebug——IE WebDeveloper js debug

热门文章

  1. 【工具相关】Web-将网站放在XAMPP上面
  2. 【读书笔记】iOS-iOS视频
  3. 6个顶级Python NLP库的比较!
  4. 根据需要扩展java中的ThreadPoolExecutor
  5. JVM vs DVM
  6. Fragment 中 ListView绑定ContextMenu
  7. Excel函数进阶
  8. 【HANA系列】SAP HANA XS使用JavaScript(JS)调用存储过程(Procedures)
  9. 常用css字体英文写法
  10. Chrome 百度搜索热点过滤插件 - 开源软件