zoukankan      html  css  js  c++  java
  • bzoj4591 [Shoi2015]超能粒子炮·改

    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

    正解:组合数学+$lucas$定理。

    $Ans=sum_{k=0}^{m}inom{n}{k} mod p$

    令$inom{n}{k} mod   p=lucas(n,k,p)$,那么由$lucas$定理,$lucas(n,k,p)=inom{n mod p}{k mod p}*lucas(n/p,k/p,p)$

    我们把上式带入$Ans$中,令$m=p*q+r$,可以发现$Ans=sum_{k=0}^{n mod p}inom{n mod p}{k}*sum_{k=0}^{q-1}inom{n/p}{k} mod p+sum_{k=0}^{r}inom{n mod p}{k}*lucas(n/p,q,p)$

    预处理出$p$以内的组合数和杨辉三角每一层的前缀和,直接写一个递归函数调用即可。

    因为递归函数和$lucas$函数的层数都不超过$log_{p}n$层,所以单次询问复杂度很低,只有大约$40$次运算。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf (1<<30)
    14 #define rhl (2333)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    19 
    20 using namespace std;
    21 
    22 ll sum[3010][3010],c[3010][3010],n,m;
    23 
    24 il ll gi(){
    25     RG ll x=0,q=1; RG char ch=getchar();
    26     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    27     if (ch=='-') q=-1,ch=getchar();
    28     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    29     return q*x;
    30 }
    31 
    32 il void pre(){
    33     sum[0][0]=c[0][0]=1;
    34     for (RG ll i=1;i<rhl;++i){
    35     sum[i][0]=c[i][0]=c[i][i]=1;
    36     for (RG ll j=1;j<i;++j){
    37         c[i][j]=c[i-1][j-1]+c[i-1][j];
    38         if (c[i][j]>=rhl) c[i][j]-=rhl;
    39         sum[i][j]=sum[i][j-1]+c[i][j];
    40         if (sum[i][j]>=rhl) sum[i][j]-=rhl;
    41     }
    42     sum[i][i]=sum[i][i-1]+1;
    43     }
    44     return;
    45 }
    46 
    47 il ll lucas(RG ll n,RG ll m){
    48     if (!m) return 1; RG ll res=c[n%rhl][m%rhl];
    49     if (!res) return 0; return res*lucas(n/rhl,m/rhl)%rhl;
    50 }
    51 
    52 il ll calc(RG ll n,RG ll m){
    53     if (m<0) return 0; if (!m) return 1;
    54     RG ll k=m/rhl,ans=sum[n%rhl][min(m-k*rhl,n%rhl)]*lucas(n/rhl,k)%rhl;
    55     return (ans+sum[n%rhl][n%rhl]*calc(n/rhl,k-1))%rhl;
    56 }
    57 
    58 int main(){
    59     File("lucas");
    60     RG ll T=gi(); pre();
    61     while (T--){
    62     n=gi(),m=gi();
    63     printf("%lld
    ",calc(n,m));
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    华为交换机配置和NTP服务器同步时间
    华为交换机常用查询命令
    Linux在线添加新磁盘
    华为交换机堆叠配置
    Linux-Centos安装nginx–解压版安装
    Linux修改为国内yum源
    pipenv的使用
    使用阿里云语音合成产品,从页面获取它的voice参数列表数据
    使用【Sonatype Nexus Repository Manager】搭建内部NPM源
    Vue3.0 项目中使用事件总线
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7111556.html
Copyright © 2011-2022 走看看