zoukankan      html  css  js  c++  java
  • [loj138]类欧几里得算法

    模板题

    定义$lfloor x floor$表示小于等于$x$的最大整数,$lceil x ceil$表示大于等于$x$的最小整数

    不难发现,若$ain Z^{+}$且$b,xin Z$,则$axle biff xle lfloorfrac{b}{a} floor$、$axge biff xge lfloorfrac{b-1}{a} floor+1$

    通过拉格朗日插值法,预处理出$S_{k}(n)=sum_{i=0}^{n}i^{k}$(定义$0^{0}=1$)关于$n$的$k+1$次多项式,并记其中的$i$次项系数为$S_{k}[i]$,即有$S_{k}(n)=sum_{i=0}^{k+1}S_{k}[i]cdot n^{i}$

    记$F_{k_{1},k_{2}}(n,a,b,c)=sum_{x=0}^{n}x^{k_{1}}lfloorfrac{ax+b}{c} floor^{k_{2}}$,问题即求该式$F_{k_{1},k_{2}}(n,a,b,c)$

    对其分类讨论:

    1.若$n<0$,那么原式即为0

    2.若$a otin [0,c)$,不妨假设$a=ic+a'$(其中$iin Z$且$a'in [0,c)$​),那么原式即
    $$
    egin{array}{ll}F_{k_{1},k_{2}}(n,a,b,c)
    &=sum_{x=0}^{n}x^{k_{1}}(lfloorfrac{a'x+b}{c} floor+ix)^{k_{2}}\
    &=sum_{x=0}^{n}x^{k_{1}}sum_{k=0}^{k_{2}}{k_{2}choose k}lfloorfrac{a'x+b}{c} floor^{k}(ix)^{k2-k}\
    &=sum_{k=0}^{k_{2}}{k2choose k}i^{k_{2}-k}F_{k_{1}+k_{2}-k,k}(n,a',b,c)end{array}
    $$
    3.若$b otin [0,c)$,不妨假设$b=ic+b'$(其中$iin Z$且$b'in [0,c)$),那么原式即
    $$
    egin{array}{ll}F_{k_{1},k_{2}}(n,a,b,c)
    &=sum_{x=0}^{n}x^{k_{1}}(lfloorfrac{ax+b'}{c} floor+i)^{k_{2}}\
    &=sum_{x=0}^{n}x^{k_{1}}sum_{k=0}^{k_{2}}{k_{2}choose k}lfloorfrac{ax+b'}{c} floor^{k}i^{k2-k}\
    &=sum_{k=0}^{k_{2}}{k2choose k}i^{k_{2}-k}F_{k_{1},k}(n,a,b',c)end{array}
    $$
    4.不为以上几种情况,先处理$k_{2}=0$的部分,即$F_{k_{1},0}(n,a,b,c)=sum_{x=0}^{n}x^{k_{1}}=S_{k_{1}}(n)$

    接下来,若$a=0$则其余部分均为0,否则原式即
    $$
    egin{array}{ll}F_{k_{1},k_{2}}(n,a,b,c)
    &=sum_{x=0}^{n}x^{k_{1}}sum_{i=0}^{lfloorfrac{ax+b}{c} floor-1}left((i+1)^{k_{2}}-i^{k_{2}} ight)\
    &=sum_{x=0}^{n}x^{k_{1}}sum_{i=0}^{lfloorfrac{ax+b}{c} floor-1}sum_{k=0}^{k_{2}-1}{k_{2}choose k}i^{k}\
    &=sum_{k=0}^{k_{2}-1}{k_{2}choose k}sum_{i=0}^{lfloorfrac{an+b}{c} floor-1}i^{k}sum_{x=lfloorfrac{ic+c-b-1}{a} floor+1}^{n}x^{k_{1}}\
    &=sum_{k=0}^{k_{2}-1}{k_{2}choose k}sum_{i=0}^{lfloorfrac{an+b}{c} floor-1}i^{k}left(S_{k_{1}}(n)-S_{k_{1}}(lfloorfrac{ic+c-b-1}{a} floor) ight)\
    &=C-sum_{k=0}^{k_{2}-1}{k_{2}choose k}sum_{i=0}^{lfloorfrac{an+b}{c} floor-1}i^{k}sum_{k'=0}^{k_{1}+1}S_{k_{1}}[k']cdot lfloorfrac{ic+c-b-1}{a} floor^{k'}\
    &=C-sum_{k=0}^{k_{2}-1}{k_{2}choose k}sum_{k'=0}^{k_{1}+1}S_{k_{1}}[k']cdot F_{k,k'}(lfloorfrac{an+b}{c} floor-1,c,c-b-1,a)end{array}
    $$
    其中$k_{2}>0$,$C$为$S_{k_{1}}(n)$对应的部分,即
    $$
    C=sum_{k=0}^{k_{2}-1}{k_{2}choose k}S_{k}(lfloorfrac{an+b}{c} floor-1)S_{k_{1}}(n)
    $$
    考虑递归计算,即对于状态$(n,a,b,c)$求出所有$k_{1},k_{2}in N^{*}$的$F_{k_{1},k_{2}}(n,a,b,c)$,注意到转移的$k_{1}+k_{2}$单调不增,因此只需要考虑$k_{1}+k_{2}le K=10$的状态即可

    由此,递归状态内的计算复杂度为$o(K^{4})$,而状态中的$a$和$c$即为辗转相除,即递归层数为$o(log n)$

    综上,时间复杂度为$o(tK^{4}log n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 15
     4 #define K 10
     5 #define mod 1000000007
     6 #define ll long long
     7 struct Data{
     8     int a[N][N];
     9     Data(){
    10         memset(a,0,sizeof(a));
    11     }
    12 };
    13 int t,n,a,b,c,k1,k2,inv[N],C[N][N],mi[N],g[N],S[N][N];
    14 void init(){
    15     inv[0]=inv[1]=1;
    16     for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
    17     for(int i=0;i<N;i++){
    18         C[i][0]=C[i][i]=1;
    19         for(int j=1;j<i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
    20     }
    21     for(int i=0;i<N;i++)mi[i]=1;
    22     for(int i=0;i<=K;i++){
    23         int s=0;
    24         for(int j=0;j<=i+1;j++){
    25             s=(s+mi[j])%mod;
    26             int sum=s;
    27             memset(g,0,sizeof(g));
    28             g[0]=1;
    29             for(int k=0;k<=i+1;k++)
    30                 if (j!=k){
    31                     sum=(ll)sum*inv[abs(j-k)]%mod;
    32                     if (j<k)sum=mod-sum;
    33                     for(int l=i+1;l;l--)g[l]=(g[l-1]-(ll)g[l]*k%mod+mod)%mod;
    34                     g[0]=mod-(ll)g[0]*k%mod;
    35                 }
    36             for(int k=0;k<=i+1;k++)S[i][k]=(S[i][k]+(ll)sum*g[k])%mod;
    37         }
    38         for(int j=0;j<N;j++)mi[j]=(ll)mi[j]*j%mod;
    39     }
    40 }
    41 int get_sum(int k,int n){
    42     int s=1,ans=0;
    43     for(int i=0;i<=k+1;i++){
    44         ans=(ans+(ll)S[k][i]*s)%mod;
    45         s=(ll)s*n%mod;
    46     }
    47     return ans;
    48 }
    49 Data dfs(int n,int a,int b,int c){
    50     Data ans;
    51     if (n<0)return ans;
    52     if (a>=c){
    53         Data s=dfs(n,a%c,b,c);
    54         mi[0]=1;
    55         for(int i=1;i<N;i++)mi[i]=(ll)mi[i-1]*(a/c)%mod;
    56         for(int k1=0;k1<=K;k1++)
    57             for(int k2=0;k1+k2<=K;k2++)
    58                 for(int k=0;k<=k2;k++)ans.a[k1][k2]=(ans.a[k1][k2]+(ll)C[k2][k]*mi[k2-k]%mod*s.a[k1+k2-k][k])%mod;
    59         return ans;
    60     }
    61     if (b>=c){
    62         Data s=dfs(n,a,b%c,c);
    63         mi[0]=1;
    64         for(int i=1;i<N;i++)mi[i]=(ll)mi[i-1]*(b/c)%mod;
    65         for(int k1=0;k1<=K;k1++)
    66             for(int k2=0;k1+k2<=K;k2++)
    67                 for(int k=0;k<=k2;k++)ans.a[k1][k2]=(ans.a[k1][k2]+(ll)C[k2][k]*mi[k2-k]%mod*s.a[k1][k])%mod;
    68         return ans;
    69     }
    70     for(int k1=0;k1<=K;k1++)ans.a[k1][0]=get_sum(k1,n);
    71     if (!a)return ans;
    72     int nn=((ll)a*n+b)/c;
    73     Data s=dfs(nn-1,c,c-b-1,a);
    74     for(int k1=0;k1<=K;k1++)
    75         for(int k2=1;k1+k2<=K;k2++)
    76             for(int k=0;k<k2;k++){
    77                 int sum=0;
    78                 for(int kk=0;kk<=k1+1;kk++)sum=(sum+(ll)S[k1][kk]*s.a[k][kk])%mod;
    79                 sum=((ll)get_sum(k,nn-1)*ans.a[k1][0]-sum+mod)%mod;
    80                 sum=(ll)sum*C[k2][k]%mod;
    81                 ans.a[k1][k2]=(ans.a[k1][k2]+sum)%mod;
    82             }
    83     return ans;
    84 }
    85 int main(){
    86     init();
    87     scanf("%d",&t);
    88     while (t--){
    89         scanf("%d%d%d%d%d%d",&n,&a,&b,&c,&k1,&k2);
    90         printf("%d
    ",dfs(n,a,b,c).a[k1][k2]);
    91     }
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    cinder支持nfs快照
    浏览器输入URL到返回页面的全过程
    按需制作最小的本地yum源
    创建可执行bin安装文件
    RPCVersionCapError: Requested message version, 4.17 is incompatible. It needs to be equal in major version and less than or equal in minor version as the specified version cap 4.11.
    惠普IPMI登陆不上
    Linux进程状态——top,ps中看到进程状态D,S,Z的含义
    openstack-neutron基本的网络类型以及分析
    openstack octavia的实现与分析(二)原理,架构与基本流程
    flask上下文流程图
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15291102.html
Copyright © 2011-2022 走看看