zoukankan      html  css  js  c++  java
  • loj 2038 / 洛谷 P4345 [SHOI2015] 超能粒子炮・改 题解

    好玩的推式子

    题目描述

    曾经发明了脑洞治疗仪与超能粒子炮的发明家 SHTSC 又公开了他的新发明:超能粒子炮・改——一种可以发射威力更加强大的粒子流的神秘装置。

    超能粒子炮・改相比超能粒子炮,在威力上有了本质的提升。它有两个参数 (n)(k),它会向每个编号为 (0)(k)(包含两端)的位置 (i) 发射威力为 (mathrm{C}_n^i mod 2333) 的粒子流。

    现在 SHTSC 给出了他的超能粒子炮・改的参数,让你求出其发射的粒子流的威力之和除以 (2333) 所得的余数。

    输入格式:

    第一行一个整数 (t) 表示数据组数。
    之后 (t) 行,每行两个整数 (n)(k),含义如题面描述。

    输出格式:

    (t) 行,每行一个整数,表示其粒子流的威力之和模 (2333) 的值。

    输入输出样例

    输入样例:

    3
    5 5
    10 7
    1145 14
    

    输出样例:

    32
    968
    763
    

    数据范围与约定

    对于 (10\%) 的数据,(t=1)(n,kle 1000)
    对于 (30\%) 的数据,(t=1)(n,kleq 1000000)
    对于 (50\%) 的数据,(t=1)(nle 10^{18},kle 1000)
    对于 (70\%) 的数据,(tle 100)(n,kle 10^{18})
    对于 (100\%) 的数据,(tle 100000)(n,kle 10^{18})

    题解:

    注:本文中所有的除法 (/)向下取整,所有的百分号 (\%) 都表示取模。

    这个题求的是 (sum_{i=0}^kmathrm{C}_n^imod 2333)。但是模数是 (2333) 因此可以考虑 Lucas 定理,即 (mathrm{C}_n^m\% p=mathrm{C}_{n\% p}^{m\% p}mathrm{C}_{n/p}^{m/p})

    我们把上面的和式推导一下,则为

    [sum_{i=0}^kmathrm{C}_{n/2333}^{i/2333}mathrm{C}_{n\%2333}^{i\%2333} ]

    然后我们发现,整个过程中 (n/2333)(n\% 2333) 是不变的。只需要关注 (i/2333)(i\%2333) 的变化规律。

    而对于连续的 (iin[2333k,2333k+2333)) 它们的 (i/2333) 是相同的,(i\%2333in[0,2333)),所以我们把需要求和的 (k) 个数分成 (leftlceilfrac{k}{2333} ight ceil) 段。其中前 (leftlfloorfrac{k}{2333} ight floor) 段一定是完整的,因此可以表示为

    [sum_{t=0}^{leftlfloorfrac{k}{2333} ight floor}mathrm{C}_{n/2333}^tsum_{i=0}^{2332}mathrm{C}_{n\%2333}^i+sum_{i=k-k\%2333}^kmathrm{C}_{n/2333}^{i/2333}mathrm{C}_{n\%2333}^{i\%2333} ]

    对于加号后面的式子,(i/2333=0),所以是对后面一个式子求和,因此可以用杨辉三角预处理,并求出前缀和,(O(1)) 解决。

    对于中间一个式子 (sum_{i=0}^{2332}mathrm{C}_{n\%2333}^i) ,因为 (n\%2333<2333) ,同理用杨辉三角。

    [sum_{i=0}^{2332}mathrm{C}_{n\%2333}^i=S,\ sum_{i=k-k\%2333}^kmathrm{C}_{n/2333}^{i/2333}mathrm{C}_{n\%2333}^{i\%2333}=A ]

    则原式为

    [Ssum_{t=0}^{leftlfloorfrac{k}{2333} ight floor}mathrm{C}_{n/2333}^t+A ]

    对于剩下的一个式子,又转化为了一个求和的子问题,因此我们递归解决。递归的边界是 (k<2333)

    因此可以在 (2333^2+O(tlog k)) 的时间复杂度内解决这个问题。

    Code:

    #include<cstdio>
    #define ll long long
    ll C[2333][2333];
    ll calc(ll n,ll t)//0~t的C_n^t
    {
        ll ans=0,p=n%2333;
        if(t/2333)
            ans=C[p][p]*calc(n/2333,t/2333-1)%2333;
        else
            return C[p][t%2333];
        ll a=n/2333,b=t/2333,tmp=1;
        while(a>=2333||b>=2333)
        {
            if(b%2333)
                tmp=tmp*(C[a%2333][b%2333]-C[a%2333][b%2333-1]+2333)%2333;
            a/=2333,b/=2333;
        }
        if(b)
            tmp=tmp*(C[a][b]-C[a][b-1]+2333)%2333;
        ans=(ans+C[p][t%2333]*tmp)%2333;
        return ans;
    }
    int main()
    {
        C[0][0]=1;
        for(int i=1;i<=2332;++i)
        {
            C[i][0]=1;
            for(int j=1;j<=i;++j)
                C[i][j]=(C[i-1][j-1]+C[i-1][j])%2333;
        }
        for(int i=0;i<=2332;++i)
            for(int j=1;j<=2332;++j)
                C[i][j]=(C[i][j-1]+C[i][j])%2333;
        int T;
        ll n,k;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lld%lld",&n,&k);
            printf("%lld
    ",calc(n,k));
        }
        return 0;
    }
    
  • 相关阅读:
    JAVA 框架
    npm安装超时,使用淘宝镜像
    使用vite搭建Vue3项目
    前端常用框架
    vue发布自己的组件库-vue3
    vue2升级vue3-基础教程
    Navicat Premium 15破解失败解决方案
    大屏
    vue使用高德地图
    vue生命周期及钩子函数
  • 原文地址:https://www.cnblogs.com/wjyyy/p/lg4345.html
Copyright © 2011-2022 走看看