HOJ 13101 The Triangle Division of the Convex Polygon(数论求卡特兰数(模不为素数))

The Triangle Division of the Convex Polygon

题意:求 n 凸多边形可以有多少种方法分解成不相交的三角形,最后值模 m。

思路:卡特兰数的例子,只是模 m 让人头疼,因为 m 不一定是素数,所以不一定存在逆元。

    解法:式子为f(n) =  ( C( 2*(n-2),  (n-2) ) / (n-1))   % m ;令 p = n-2, 式子可化为:f(p) = ((2*p)! / ( p! * (p+1)! ) ) % m;

      对 s!分解质因素,统计个数。设小于等于 s 的素数为 p1, p2, p3, ... , pk;

      则各个素因子个数为 :

  for i = 1 to k
      q  = s
      num(i) = 0
      while q > 0
          q = q / pi
          num(i) += q
      end while
  end for

      所以,我们就可以统计出 f(p) 的素因子及个数,分子 + , 分母 - 。最后计算时用快速幂。

代码:

#include <climits>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cstdarg>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <exception>
#include <stdexcept>
#include <memory>
#include <locale>
#include <bitset>
#include <deque>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
#include <string>
#include <complex>
#include <valarray>

using namespace std;

typedef long long ll;

const int N = 1e6+7;

bool tag[N];
int p[N>>3];
int t;

void prime() {
    t = 0;
    memset(tag, 0, sizeof tag);
    p[t++] = 2, tag[4] = 0;
    for(int i = 3; i < N; i += 2) {
        if(!tag[i]) p[t++] = i;
        for(int j = 0, k; j < t && (k = i * p[j]) < N; ++j) {
            tag[k] = 1;
            if(i % p[j] == 0) break;
        }
    }
    return ;
}

int n;
ll m, ans;

int zp[N>>3], mp[N>>3];
int tz, tp;

int Factor(int q[], int u) {   //分解 n!
    int i;
    for( i = 0; i < t && p[i] <= u; ++i) {
        int v = u;
        while(v) {
            v /= p[i];
            q[i] += v;
        }
    }
    return i;
}

void cat(int n) {
    int nn = n + n;
    tz = tp = 0;
    memset(zp, 0, sizeof zp);
    memset(mp, 0, sizeof mp);

    tz = Factor(zp, nn);
    tp = Factor(mp, n);
    tp = Factor(mp, n+1);

    for(int i = 0; i < tp; ++i) zp[i] -= mp[i];

    return ;
}

ll mult_mod(int a, int b, ll m) {
    ll res = 1LL, tt = (ll) a;
    while(b) {
        if(b&1) res = (res * tt) % m;
        tt = tt * tt % m;
        b >>= 1;
    }
    return res;
}

void solve() {
    n -= 2;
    cat(n);
    ans = 1LL;
    for(int i = 0; i < tz; ++i) {
        ans = (ans * mult_mod(p[i], zp[i], m)) % m;
    }
    printf("%I64d\n", ans);
}

int main()
{
#ifdef PIT
    freopen("c.in", "r", stdin);
#endif // PIT
    prime();
    while (~scanf("%d %I64d", &n, &m)) {
        solve();
    }

    return 0;
}
时间: 2024-10-14 15:17:21

HOJ 13101 The Triangle Division of the Convex Polygon(数论求卡特兰数(模不为素数))的相关文章

HNU 13101 The Triangle Division of the Convex Polygon 卡特兰数第n项%m(m可为非素数

题目链接:点击打开链接 首先要n-=2,然后就是一个卡特兰数了. 上一题用的是 h(n) = h(n-1) * (4n-2)/(n+1); 这题用的是 h(n) = (2n)! * n! / (n+1)!; 然后对阶乘分解质因数: 点击打开链接 分解完了直接快速幂. #include<stdio.h> #include<iostream> #include<cmath> #include<cstring> using namespace std; #defi

hunnu11562:The Triangle Division of the Convex Polygon(第n个卡特兰数取模)

Problem description   A convex polygon with n edges can be divided into several triangles by some non-intersect diagonals. We denote d(n) is the number of the different ways to divide the convex polygon. For example,when n is 6,there are 14 different

HUNAN 11562 The Triangle Division of the Convex Polygon(大卡特兰数)

http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11562&courseid=0 求n边形分解成三角形的方案数. 就是求n-2个卡特兰数,从大神那盗取了一份模板,效率极高.同时也很复杂. 1 #include <cstdio> 2 #include <cmath> 3 #include <stdlib.h> 4 #include <memory.h> 5 type

[LeetCode] Convex Polygon 凸多边形

Given a list of points that form a polygon when joined sequentially, find if this polygon is convex (Convex polygon definition). Note: There are at least 3 and at most 10,000 points. Coordinates are in the range -10,000 to 10,000. You may assume the

Leetcode: Convex Polygon

Given a list of points that form a polygon when joined sequentially, find if this polygon is convex (Convex polygon definition). Note: There are at least 3 and at most 10,000 points. Coordinates are in the range -10,000 to 10,000. You may assume the

LeetCode469 - Convex Polygon - Medium (Python)

Given a list of points that form a polygon when joined sequentially, find if this polygon is convex (Convex polygon definition). [[0,0],[0,1],[1,1],[1,0]] Answer: True [[0,0],[0,10],[10,10],[10,0],[5,5]] Answer: False 思路:这题问的是给一系列polygon的点,判断其是否是conv

sgu100~199题解

老东西了..发上来吧.. Sgu题解系列  南开中学邹事成 100:A+B略 101:Domino 给n块多米诺骨牌,每张骨牌两端各有从1到6的一个数字,现在要把这些骨牌排成一列,使相邻的两块骨牌相对的面所写的数字一样. 可以把每一块多米诺骨牌想象成一条边,把面上写的数字抽象成点,比如一块骨牌正面写的1反面写的2就想象成连了一条从1到2的边,那么这就是求一条有重边的欧拉回路了,dfs一下即可. 102:Coprimes给定n求从1到n中与n互质的数的个数. 可以把n质因数分解后直接代入欧拉函数.

Spoj-TRNGL Make Triangle

Make Triangle Chayanika loves Mathematics. She is learning a new chapter geometry. While reading the chapter a question came in her mind. Given a convex polygon of n sides. In how many ways she can break it into triangles, by cutting it with (n-3) no

hdu 3304 Interesting Yang Yui Triangle

题意: 给出P,N,问第N行的斐波那契数模P不等于0的有多少个? 限制: P < 1000,N <= 10^9 思路: lucas定理, 如果: n = a[k]*p^k + a[k-1]*p^(k-1) + ... + a[1]*p + a[0] m = b[k]*p^k + b[k-1]*p^(k-1) + ... + b[1]*p + b[0] 则: C(n,m) = pe(i=0~k,C(a[i],b[i]))%p 其中pe表示连乘符号. 由于n已经确定,所以a[i] (0 <=