• Bzoj 4591: [Shoi2015]超能粒子炮·改 数论,Lucas定理,排列组合


    4591: [Shoi2015]超能粒子炮·改

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 178  Solved: 70
    [Submit][Status][Discuss]

    Description

    曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加
    强大的粒子流的神秘装置。超能粒子炮·改相比超能粒子炮,在威力上有了本质的提升。它有三个参数n,k。它会
    向编号为0到k的位置发射威力为C(n,k) mod 2333的粒子流。现在SHTSC给出了他的超能粒子炮·改的参数,让你求
    其发射的粒子流的威力之和模2333。

    Input

    第一行一个整数t。表示数据组数。
    之后t行,每行二个整数n,k。含义如题面描述。
    k<=n<=10^18,t<=10^5

    Output

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

    Sample Input

    1
    5 5

    Sample Output

    32

    HINT

     

    Source

    By 佚名上传

    题解:

    Lucas定理:C(n,k)%p=(C(n/p,k/p)*C(n%p,k%p))%p    (p为质数)

    C(n,k)%2333=C(n/2333,k/2333)*C(n%2333,k%2333)
     
    分两种部分考虑:
    设k=k1*2333+k2 (0≤k1,k2)
    1.对于k1部分
    C(n,0)……C(n,2332)
    =C(n/2333,0)*C(n%2333,0)+C(n/2333,0)*C(n%2333,1)+……+C(n/2333,0)*C(n%2333,2332) = C(n/2333,0)*(∑C(n%2333,i)(0≤i≤2332)) ==> 2333个
    C(n,2333)……C(n,4665)
    =C(n/2333,1)*C(n%2333,0)+C(n/2333,1)*C(n%2333,1)+……+C(n/2333,1)*C(n%2333,2332) = C(n/2333,1)*(∑C(n%2333,i)(0≤i≤2332)) ==> 2333个
    C(n,4666)……C(n,6998)
    =C(n/2333,2)*C(n%2333,0)+C(n/2333,2)*C(n%2333,1)+……+C(n/2333,2)*C(n%2333,2332) = C(n/2333,2)*(∑C(n%2333,i)(0≤i≤2332)) ==> 2333个
    C(n,6999)……C(n,9331)
    =C(n/2333,3)*C(n%2333,0)+C(n/2333,3)*C(n%2333,1)+……+C(n/2333,3)*C(n%2333,2332) = C(n/2332,3)*(∑C(n%2333,i)(0≤i≤2332)) ==> 2333个
    …………
    所以k1部分的总和sum=(∑C(n%2333,i)(0≤i≤2332))*(∑C(n/2333,j)(0≤j≤k1-1))
     
    2.对于k2部分
    C(n,k1*2333)……C(n,k)
    =C(n/2333,k1)*C(n%2333,0)+C(n/2333,k1)*C(n%2333,1)+……+C(n/2333,k1)*C(n%2333,k%2333) ==> k%2333+1个
    =C(n/2333,k1)*(∑C(n%2333,i)(0≤i≤k%2333))
     
    由以上可得ans=(∑C(n%2333,i)(0≤i≤2332))*(∑C(n/2333,j)(0≤j≤k1-1))+C(n/2333,k1)*(∑C(n%2333,i)(0≤i≤k%2333))
     
    预处理 S(n,k)=∑C(n,i)(0≤i≤k),化简ans=S(n%2333,2332)*(∑C(n/2333,j)(0≤j≤k1-1))+C(n/2333,k1)*S(n%2333,k%2333)
    因为n%2333一定小于2333,所以可以用二维数组S(n,k)表示。但 ∑C(n/2333,j)(0≤j≤k1-1) 中n/2333可能很大,无法用二维数组存储,所以不把 ∑C(n/2333,j)(0≤j≤k1-1) 化简为 S(n/2333,k1-1)。但是可以发现 ∑C(n/2333,j)(0≤j≤k1-1) 与 要求的最终答案的公式的格式 ∑C(n,i)(0≤i≤k) 一样,所以可以递归求解。另外ans中的C(n/2333,k1)可以用Lucas定理求解。
     
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 #define MOD 2333
     5 LL jc[MOD+10],C[MOD+10][MOD+10],S[MOD+10][MOD+10];
     6 LL read()
     7 {
     8     LL s=0,fh=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    11     return s*fh;
    12 }
    13 LL mod(LL k,LL k1){return k-(k/k1)*k1;}
    14 void cljc()
    15 {
    16     jc[0]=1LL;
    17     for(int i=1;i<=MOD;i++)jc[i]=mod(jc[i-1]*i,MOD);
    18 }
    19 void clC()
    20 {
    21     int i,j;
    22     C[0][0]=1LL;
    23     for(i=1;i<=MOD;i++)
    24     {
    25         C[i][0]=C[i][i]=1LL;
    26         for(j=1;j<i;j++)C[i][j]=mod(C[i-1][j]+C[i-1][j-1],MOD);
    27     }
    28     for(i=0;i<=MOD;i++)
    29     {
    30         S[i][0]=1LL;
    31         for(j=1;j<=MOD;j++)S[i][j]=mod(S[i][j-1]+C[i][j],MOD);
    32     }
    33 }
    34 LL ksm(LL bb,LL pp,LL kk)
    35 {
    36     LL s=1LL;
    37     while(pp>0)
    38     {
    39         if(pp%2!=0)s=mod(s*bb,kk);
    40         pp/=2;
    41         bb=mod(bb*bb,kk);
    42     }
    43     return s;
    44 }
    45 LL Comb(LL n,LL m,LL p)
    46 {
    47     if(m>n)return 0LL;
    48     if(m>n-m)m=n-m;
    49     return mod(jc[n]*ksm(mod(jc[m]*jc[n-m],p),p-2,p),p);
    50 }
    51 LL Lucas(LL n,LL m,LL p)
    52 {
    53     if(m==0LL)return 1LL;
    54     return mod(/*Comb(mod(n,p),mod(m,p),p)*/C[n%p][m%p]*Lucas(n/p,m/p,p),p);
    55 }
    56 LL getans(LL n,LL m,LL p)
    57 {
    58     if(m<0LL)return 0LL;
    59     return mod(mod(S[mod(n,2333)][2332]*getans(n/2333,m/2333-1,p),p)+mod(Lucas(n/2333,m/2333,p)*S[mod(n,2333)][mod(m,2333)],p),p);
    60 }
    61 int main()
    62 {
    63     LL T,n,k;
    64     cljc();
    65     clC();
    66     T=read();
    67     while(T--)
    68     {
    69         n=read();k=read();
    70         printf("%lld
    ",getans(n,k,MOD));
    71     }
    72     fclose(stdin);
    73     fclose(stdout);
    74     return 0;
    75 }
  • 相关阅读:
    图像相似度
    二维数组 问题 E: 计算鞍点
    Uva
    Uva
    Uva
    Uva
    Uva
    Uva
    Uva
    【转载】2015 Objective-C 三大新特性 | 干货
  • 原文地址:https://www.cnblogs.com/Var123/p/5523068.html
Copyright © 2020-2023  润新知