• 牛客小白月赛6 水题 求n!在m进制下末尾0的个数 数论


    链接:https://www.nowcoder.com/acm/contest/135/C
    来源:牛客网

    题目描述

    其中,f(1)=1;f(2)=1;Z皇后的方案数:即在Z×Z的棋盘上放置Z个皇后,使其互不攻击的方案数。

    输入描述:

    输入数据共一行,两个正整数x,m,意义如“题目描述”。

    输出描述:

    一个正整数k,表示输出结尾0 的个数或者放置皇后的方案数
    示例1

    输入

    复制
    375 16

    输出

    复制
    14200

    说明

       鸣谢真·dalao  Tyxao
     
    分析:打表题目中的公式容易得到:f(n) = f(n-1) + f(n-2) (n>=3) 因为x最大取到10^18,所以我们打表前90位就可以了
      然后判断x是否等于前九十项中一项的值,如果等于就计算x!在m进制下末尾0的个数,如果不等于输出a[x%min(13,m)+1],a数组13*13棋盘下每种皇后的个数(类似八皇后,dfs求就可以了)
      重点来看x!在m进制下末尾0的个数
      十进制下:500 = 5*10^2  五进制下: 300 = 3*5^2
      所以:m进制下:x = a*m^k,因为任意一个大于1的数都可以表示为几个质数的乘积
      所以:a*m^k = a*(p1^k1*p2^k2*...*pn^kn)^k = a*(p1^k1k*p2^k2k*...*pn^knk) = a*(p^d1*p2^d2*...*pn^dn)
      我们要求的 k = min(p1,p2,...,pn)
    AC代码:
    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <bitset>
    #include <cstring>
    #include <iomanip>
    #include <iostream>
    #include <algorithm>
    #define ls (r<<1)
    #define rs (r<<1|1)
    #define debug(a) cout << #a << " " << a << endl
    using namespace std;
    typedef long long ll;
    const ll maxn = 1e6+10;
    const double eps = 1e-8;
    const ll mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const double pi = acos(-1.0);
    ll f[100]={-1,1,0,0,2,10,4,40,92,352,724,2680,14200,73712,365596};
    ll prime[] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
    ll getcnt( ll p, ll x ) {
        ll res = 0;
        while(x) {
            res += x/p;
            x /= p;
        }
        return res;
    }
    int main() {
        ios::sync_with_stdio(0);
        ll a[105];
        a[1] = 1, a[2] = 1;
        for( ll i = 3; i <= 92; i ++ ) {
            a[i] = a[i-1] + a[i-2];
        }
        ll x, m;
        cin >> x >> m;
        bool flag = false;
        for( ll i = 1; i <= 92; i ++ ) {
            if( a[i] == x ) {
                flag = true;
                break;
            }
        }
        if( flag ) {
            map<ll,ll> mp;
            vector<pair<ll,ll> > e;
            for( ll i = 1; i <= 25; i ++ ) {
                while(m%prime[i]==0) {  //m中有多个相同的质数
                    mp[prime[i]] ++;
                    m /= prime[i];
                }
            }
            for( auto i : mp ) {
                e.push_back(make_pair(i.second,getcnt(i.first,x)));
            }
            ll k = 1e18+1;
            for( ll i = 0; i < e.size(); i ++ ) {
                k = min(k,e[i].second/e[i].first);  //因为质数可能有多个,所以求的质数还要除以质数的个数
            }
            cout << k << endl;
        } else {
            cout << f[x%min((ll)13,m+1)+1] << endl;
        }
        return 0;
    }
    

      

    彼时当年少,莫负好时光。
  • 相关阅读:
    2-4 递增链表的插入 链表
    KMPnext数组自看
    Shortest Prefixes POJ
    Xor Sum HDU
    Immediate Decodability HDU
    Repository HDU
    "strcmp()" Anyone? UVA
    Remember the Word UVALive
    A Magic Lamp HDU
    Check Corners HDU
  • 原文地址:https://www.cnblogs.com/l609929321/p/9529395.html
Copyright © 2020-2023  润新知