zoukankan      html  css  js  c++  java
  • 【LOJ】#2038. 「SHOI2015」超能粒子炮・改

    题解

    用lucas随便分析一波就出来了

    (inom{n}{k} = inom{n % p}{k % p}inom{n / p}{k / p})
    那么对于一个余数r,如果r <= k % p
    那么它还要乘上
    (sum_{i = 0}^{lfloor frac{k}{p} floor} inom{lfloor frac{n}{p} floor % p}{i})
    这显然是个相同的问题,可以递归
    如果r > k % p那么会比前一个问题少乘一个(inom{lfloor frac{n}{p} floor % p}{lfloor frac{k}{p} floor})
    这样我们处理下2333以内每行组合数的前缀和,再递归处理,可以用(log^2 n)的复杂度内解决,但是别忘了底数是p,超级快的。。。

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define MAXN 200005
    #define pb push_back
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 + c - '0';
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    const int MOD = 2333;
    int C[2335][2335],S[2335][2335];
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return a * b % MOD;
    }
    int Cnm(int64 n,int64 m) {
        int res = 1;
        while(1) {
            if(n < m || !res) {return 0;}
            if(n == 0) break;
            res = mul(res,C[n % MOD][m % MOD]);
            n /= MOD;m /= MOD;
        }
        return res;
    }
    int Calc(int64 n,int64 k) {
        if(!n) return 1;
        int64 t = k / MOD;int r = k % MOD;
        int h2 = Cnm(n / MOD,t);
        int h1 = Calc(n / MOD,t);
        h2 = inc(h1,MOD - h2);
        return inc(mul(S[n % MOD][r],h1),mul(inc(S[n % MOD][MOD - 1],MOD - S[n % MOD][r]),h2));
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        C[0][0] = 1;
        for(int i = 1 ; i < MOD ; ++i) {
            C[i][0] = 1;
            for(int j = 1 ; j <= i ; ++j) {
                C[i][j] = inc(C[i - 1][j - 1],C[i - 1][j]);
            }
        }
        for(int i = 0 ; i < MOD ; ++i) {
            S[i][0] = 1;
            for(int j = 1 ; j < MOD ; ++j) {
                S[i][j] = inc(S[i][j - 1],C[i][j]);
            }
        }
        int T;
        int64 N,K;
        read(T);
        while(T--) {
            read(N);read(K);
            out(Calc(N,K));enter;
        }
        return 0;
    }
    
  • 相关阅读:
    thinkphp使用ajax程序报500错误
    非隐藏转发和隐藏转发的区别及选择
    表单文件(图片)上传到服务器,权限自动变成363,无法访问
    我收到了互联网应急中心的通报!记sqlmap的正确打开方式。
    css字体可以小于12px!被小米官网打脸
    阿里云CDN添加域名80端口和443端口什么区别?
    网站使用海外服务器,国内访问很慢的解决方案
    linux下设置php文件不区分大小写
    国际化
    Spring boot2.0学习笔记(一)
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9491292.html
Copyright © 2011-2022 走看看