• uva 11174(排列组合+搜索)


    依然是liurujia计数练习题。依然是自己想没想出来,在MOD是素数的情况下除以x即为乘x的逆。这个真心以前没听过,用了这个方法后处理就变得十分巧妙。

    整个程序步骤还是很清晰的,先上来算阶乘与逆(求数的逆还是有点没理解透,需要后续章节继续学习)。然后读入建图只能用邻接表了,注意加上最开始的那个根节点就行了。

    然后就是搜索按照书上的公式计算就行了。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 #include <cmath>
     6 #include <algorithm>
     7 #define LEN 40100
     8 #define MOD 1000000007
     9 #define ll long long
    10 using namespace std;
    11 
    12 int n, m, isrt[LEN];
    13 ll jc[LEN], rjc[LEN], ans;
    14 vector<ll> map[LEN];
    15 
    16 //扩展欧几里德
    17 ll extend_gcd(ll a, ll b, ll &x,ll &y){
    18    ll t,_m;
    19    if ((b==0)&(a==0)) return -1;//表示无最大公因数
    20    if (b==0){
    21          x=1;y=0;       return a;
    22    }
    23    else {
    24          _m=extend_gcd(b,a % b,x,y);
    25          t=x;x=y;y=t-(a/b)*y;
    26    }
    27    return _m;
    28 }
    29 
    30 //初始化阶乘和他的逆
    31 void cntjc()
    32 {
    33     ll x,y;
    34     jc[0] = 1;
    35     for(int i=1; i<LEN; i++){
    36         jc[i] = (jc[i-1]*i)%MOD;
    37         ll ta = extend_gcd(i,MOD,x,y);
    38         if(ta==1 || ta==-1) rjc[i] = (x+MOD)%MOD;
    39         else rjc[i] = -1;
    40     }
    41 }
    42 
    43 void init()
    44 {
    45     memset(isrt, 0, sizeof isrt);
    46     for(int i=0; i<LEN; i++){
    47         map[i].clear();
    48     }
    49     //建图
    50     int a, b;
    51     scanf("%d%d", &n, &m);
    52     for(int i=0; i<m; i++){
    53         scanf("%d%d", &a, &b);
    54         map[b].push_back(a);
    55         isrt[a] = 1;
    56     }
    57     //加入总的根节点
    58     for(int i=1; i<=n; i++){
    59         if(!isrt[i]) map[0].push_back(i);
    60     }
    61 }
    62 
    63 int DFS(int vex)
    64 {
    65     int cnt = 1;
    66     for(vector<ll>::iterator it=map[vex].begin(); it!=map[vex].end(); ++it){
    67         cnt+=DFS(*it);
    68     }
    69     if(vex) ans = ans*rjc[cnt]%MOD;
    70     return cnt;
    71 }
    72 
    73 int main()
    74 {
    75 //    freopen("in.txt", "r", stdin);
    76 
    77     int T;
    78     scanf("%d", &T);
    79     cntjc();
    80     while(T--)
    81     {
    82         init();
    83         ans = jc[n];
    84         DFS(0);
    85         printf("%lld
    ", ans);
    86     }
    87     return 0;
    88 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    最有价值的专家--微软官方网站
    CC++初学者编程教程(16) 搭建Xcode cocos2dx开发环境--尹成老师博客
    微软最具价值的专家之毛星云博客
    Winsock IO模型之IOCP模型
    IOCP模型与网络编程
    关于proc索引的创建
    查找表存在于那些proc中
    Sql 时间做条件
    Sql 无指定条件,防并发update
    sql 根据客户需用 增减查询字段
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3413540.html
Copyright © 2020-2023  润新知