BZOJ4591——[Shoi2015]超能粒子炮·改

1、题意:求 C(n,0)+C(n,1)+...+C(n,k)mod2333

2、分析:公式恐惧症的同学不要跑啊QAQ

根据lucas定理——

answer=C(n,0)+C(n,1)+...+C(n,k)mod2333

=C(n/2333,0)?C(nmod2333,0)+C(n/2333,0)?C(nmod2333,1)+...+C(n/2333,k/2333)?C(nmod2333,kmod2333)

这一步大家都能懂吧,这是浅而易见的lucas定理转化过程,将每一项拆分成两项

那么下一步,我们将同类项合并

我们观察可以发现1..2332 / 2333都是0

那么我们将其中2332项提取出来变成

C(n/2333,0)?(C(nmod2333,0)+...+C(mod2333,2332))

同理,2333..4665 / 2333都是1,我们同样提出这个公因式

因此可以得到

C(n/2333,1)?(C(nmod2333,0)+...+C(mod2333,2332))

接下去,我们可以以的到达k/2333-1这里,都是类似的

那么我们提取(C(nmod2333,0)+...+C(mod2333,2332)),得到

(C(n/2333,0)+C(n/2333,1)+...+C(n/2333,k/2333?1))?(C(nmod2333,0)+...+C(mod2333,2332))

我们完成了一部分,那么剩下的还有k/2333的这一部分,我们依旧提取公因式

C(n/2333,k/2333)?(C(nmod2333,0)+...+C(nmod2333,kmod2333))

那么我们令sum(i,j) 为 C(i,0)+C(i,1)+...+C(i,j)

我们可以得到最终答案的式子

ans(n,k)mod2333=(∑C(n/2333,j)(0≤j<k/2333))?sum(nmod2333)+C(n/2333,k/2333)?sum(nmod2333,kmod2333)

我们观察这个式子(∑C(n/2333,j)(0≤j<k/2333)),他简直就是这个问题的简化版

那么这个式子其实是等于ans(n/2333,k/2333?1) 的,十分浅显易懂,那么我们就可以将此题不断的缩小再缩小,注意那个C数组和sum数组都预处理出来,只预处理小于2333的,太大的C用lucas定理解决,完美解决,撒花!

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 2500
#define MOD 2333
#define LL long long

inline int read(){
    char ch = getchar(); int x = 0, f = 1;
    while(ch < ‘0‘ || ch > ‘9‘){
        if(ch == ‘-‘) f = -1;
        ch = getchar();
    }
    while(‘0‘ <= ch && ch <= ‘9‘){
        x = x * 10 + ch - ‘0‘;
        ch = getchar();
    }
    return x * f;
}

inline LL llread(){
    char ch = getchar(); LL x = 0, f = 1;
    while(ch < ‘0‘ || ch > ‘9‘){
        if(ch == ‘-‘) f = -1;
        ch = getchar();
    }
    while(‘0‘ <= ch && ch <= ‘9‘){
        x = x * 10 + ch - ‘0‘;
        ch = getchar();
    }
    return x * f;
}

int c[M][M], sum[M][M];  

inline void init(){
    c[0][0] = sum[0][0] = 1;
    for(int i = 1; i < MOD; i ++) sum[0][i] = 1;
    for(int i = 1; i < MOD; i ++){
        sum[i][0] = c[i][0] = 1;
        for(int j = 1; j <= i; j ++) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
        for(int j = 1; j < MOD; j ++) sum[i][j] = (sum[i][j - 1] + c[i][j]) % MOD;
    }
}

inline int Lucas(LL x, LL y){
    if(x < y || y < 0) return 0;
    if(x < MOD && y < MOD) return c[x][y];
    return Lucas(x / MOD, y / MOD) * c[x % MOD][y % MOD] % MOD;
}  

inline int cal(LL n, LL k){
    if(k < 0) return 0;
    return (cal(n / MOD,k / MOD - 1) * sum[n % MOD][MOD - 1] % MOD + Lucas(n / MOD, k / MOD) * sum[n % MOD][k % MOD] % MOD) % MOD;
}  

int main(){
    init();
    int T = read();
    while(T --){
        LL n = llread(), k = llread();
        printf("%d\n", cal(n, k));
    }
    return 0;
}
时间: 2024-11-06 22:20:51

BZOJ4591——[Shoi2015]超能粒子炮·改的相关文章

bzoj4591[Shoi2015]超能粒子炮&#183;改

bzoj4591[Shoi2015]超能粒子炮·改 题意: 求(sigma(i,0,k)C(n,i))%2333.n,k≤1018 题解: 根据Lucas定理(我不会),C(n,k)%2333=C(n/2333,k/2333)*C(n%2333,k%2333),故可以进行一些化简(把模省去了) (sigma(i,0,k)C(n,i))=sigma(i,0,k)C(n/2333,i/2333)*C(n%2333,i%2333) =sigma(i,0,k/2333-1)C(n/2333,i)*(si

BZOj-4591: [Shoi2015]超能粒子炮&#183;改 (Lucas+排列组合)

4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 960  Solved: 360[Submit][Status][Discuss] Description 曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加 强大的粒子流的神秘装置.超能粒子炮·改相比超能粒子炮,在威力上有了本质的提升.它有三个参数n,k.它会 向编号为0到k的位置发射威力为C(

bzoj4591 / P4345 [SHOI2015]超能粒子炮&#183;改

P4345 [SHOI2015]超能粒子炮·改 题意:求$\sum_{i=1}^{k}C(n,i)\%(P=2333)$ 肯定要先拆开,不然怎么做呢(大雾) 把$C(n,i)$用$lucas$分解一下 于是原式$=\sum_{i=1}^{k}C(n/P,k/P)*C(n\%P,k\%P)\%P$ 发现介个$k/P$是可以用整除分块搞的 于是拆开各个分块 $=C(n/P,0)*\sum_{i=0}^{P-1}C(n\%P,i)$ $+C(n/P,1)*\sum_{i=0}^{P-1}C(n\%P,

Bzoj 4591: [Shoi2015]超能粒子炮&#183;改 数论,Lucas定理,排列组合

4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 178  Solved: 70[Submit][Status][Discuss] Description 曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加 强大的粒子流的神秘装置.超能粒子炮·改相比超能粒子炮,在威力上有了本质的提升.它有三个参数n,k.它会 向编号为0到k的位置发射威力为C(n

【bzoj4591】 [Shoi2015]超能粒子炮&#183;改

Description 曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加 强大的粒子流的神秘装置.超能粒子炮·改相比超能粒子炮,在威力上有了本质的提升.它有三个参数n,k.它会 向编号为0到k的位置发射威力为C(n,k) mod 2333的粒子流.现在SHTSC给出了他的超能粒子炮·改的参数,让你求 其发射的粒子流的威力之和模2333. Input 第一行一个整数t.表示数据组数. 之后t行,每行二个整数n,k.含义如题面描述. k<

【bzoj4591】[Shoi2015]超能粒子炮&#183;改 Lucas定理

题目描述 曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加强大的粒子流的神秘装置.超能粒子炮·改相比超能粒子炮,在威力上有了本质的提升.它有三个参数n,k.它会向编号为0到k的位置发射威力为C(n,k) mod 2333的粒子流.现在SHTSC给出了他的超能粒子炮·改的参数,让你求其发射的粒子流的威力之和模2333. 输入 第一行一个整数t.表示数据组数. 之后t行,每行二个整数n,k.含义如题面描述. k<=n<=10^18

P4345 [SHOI2015]超能粒子炮&#183;改 Lucas

\(\color{#0066ff}{ 题目描述 }\) 曾经发明了脑洞治疗仪与超能粒子炮的发明家 SHTSC 又公开了他的新发明:超能粒子炮?改--一种可以发射威力更加强大的粒子流的神秘装置. 超能粒子炮?改相比超能粒子炮,在威力上有了本质的提升.它有两个参数\(n\),\(k\),它会向每个编号为\(0\)到\(k\)(包含两端)的位置\(i\)发射威力为\(C_{n}^{i} mod 2333\)的粒子流. 现在 SHTSC 给出了他的超能粒子炮?改的参数,让你求出其发射的粒子流的威力之和除

P4345 [SHOI2015]超能粒子炮&#183;改

传送门 看到数据和模数大小就知道要上 lucas 了 然后开始愉快地推公式: 答案为 $\sum _{i=0}^kC_{n}^{i}\ (mod\ 2333)$ 设 $f [ i ] [ j ] = \sum _{k=0}^jC_{i}^{k}\ (mod\ 2333)\ ,\ P=2333$ 那么根据 lucas 定理得 $f[n][k]=\sum _{i=0}^k {C_{n\%P}^{i\%P}C_{n/P}^{i/p}}$ 看到 $i/P$ 容易想到整除分块,那就把 $i/P$ 相同的块

【[SHOI2015]超能粒子炮&#183;改】

就是运用\(Lucas\)推一个柿子 首先是前置芝士\(Lucas\)定理 \[C_{n}^{m}\%p=C_{n/p}^{m/p}*C_{n\%p}^{m\%p}\%p\] 至于证明 我建议去问一下Lucas本人 至于这道题,我们要求的是这个柿子 \[\sum_{i=0}^kC_{n}^i\%p\] 于是我们设\(f(n,k)=\sum_{i=0}^kC_{n}^i\) 我们就可以化柿子啦 \[f(n,k)=\sum_{i=0}^kC_{n}^i\] \[\text{ }\text{ }\te