• [luogu7468]愤怒的小N


    定义$count(x)$为$x$二进制下1的个数,答案即$sum_{0le x<n,count(x)equiv 1(mod 2)}f(x)$

    考虑预处理出$S_{k,i,p}=sum_{0le x<2^{i},count(x)equiv p(mod 2)}x^{k}$,可以对$x$最高位是否为1分类讨论,转移即
    $$
    S_{k,i,p}=S_{k,i-1,p}+sum_{0le x<2^{i-1},count(x) otequiv p(mod 2)}(x+2^{i-1})^{k}=S_{k,i-1,p}+sum_{j=0}^{k}2^{(i-1)(k-j)}{kchoose j}S_{j,i-1,poplus 1}
    $$
    $k$的枚举范围即$o(k)$,$i$的枚举范围即$o(log n)$,因此预处理复杂度为$o(k^{2}log n)$

    更进一步的,假设给定字符串为$n_{i}$(下标从0开始,且假设长度为$l$),枚举与其相同的前缀长度,答案即
    $$
    sum_{0le i<l,n_{i}=1}sum_{0le j<2^{l-i-1}-1,count(j) otequiv p(mod 2)}f(lst+j)
    $$
    (其中$p=sum_{j=0}^{i-1}n_{j}$,$lstequiv sum_{j=0}^{i-1}n_{j}2^{l-j-1}$)

    对后者展开并化简,即
    $$
    sum_{0le i<l,n_{i}=1}sum_{t_{1}=0}^{k-1}a_{t_{1}}sum_{t_{2}=0}^{t_{1}}{t_{1}choose t_{2}}lst^{t1-t2}S_{t_{2},l-i-1,poplus 1}
    $$
    这里的计算复杂度也是$o(k^{2}log n)$,两者的复杂度都无法通过

    打表可以发现$S_{k,i,0}=S_{k,i,1}$在$k<i$时成立,具体证明如下——

    考虑对$i$进行归纳,即在$i=i_{0}$时成立,来证明$i=i_{0}+1$也成立

    首先$0le kle i_{0}$,再对$k$分类讨论:

    1.若$k<i_{0}$,考虑转移式中的每一项都有$k<i=i_{0}$小,根据归纳即成立

    2.若$k=i_{0}$,具体代入转移,唯一无法证明相同的两项恰为$S_{k,i_{0},p}$以及$S_{k,i,poplus 1}$,两者具有对称性,即也相等

    综上,我们即得到此结论

    对于预处理,可以强制$ile j$,那么状态数为$o(k^{2})$,预处理复杂度即降为$o(k^{3})$

    当$t_{2}<l-i-1$,显然此时$i$的范围是$o(k)$的,暴力计算复杂度也是$o(k^{3})$的

    当$t_{2}ge l-i-1$,考虑$S_{k,i,0}+S_{k,i,1}=sum_{j=0}^{2^{i}-1}j^{k}$,即$S_{t_{2},l-i-1,poplus 1}=frac{sum_{j=0}^{2^{l-i-1}-1}j^{t_{2}}}{2}$

    将之代入,并将$j$的枚举提到前面,即$frac{sum_{0le i<l,n_{i}=1}sum_{j=0}^{2^{l-i-1}-1}f(j)}{2}$,对后者通过$o(k^{3})$对$f(x)$的前缀和插值预处理处这个$k$次多项式,即可$o(k)$计算,那么总复杂度即$o(k^{3}+klog n)$

    但这样还是无法通过,考虑令$ans_{p}=sum_{0le x<n,count(x)equiv p(mod 2)}f(x)$,所求的$ans_{1}$也可以看作是$frac{(ans_{0}+ans_{1})-(ans_{0}-ans_{1})}{2}$,对前后两者分类讨论:

    对于前者,实际意义即$sum_{i=0}^{n-1}f(i)$,由于已经确定是$n-1$的前缀和,可以$o(k^{2})$插值计算

    对于后者,用同样的方式计算,仅是将统计答案时变为$S_{t_{2},l-i-1,poplus 1}-S_{t_{2},l-i-1,poplus 0}$,这对于$t_{2}<l-i-1$只需要改变一下式子即可,对于$t_{2}ge l-i-1$可以发现该式即为0,因此$o(klog n)$的部分就被优化了

    综上,这一做法的复杂度是$o(k^{3}+log n)$,可以通过

    (然而代码还是TLE了,应该只是常数问题QAQ)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 500005
     4 #define K 505
     5 #define mod 1000000007
     6 int n,k,ans,a[K],mi[N],fac[K],inv[K],x[K],y[K],f[K][K][2];
     7 char s[N];
     8 int c(int n,int m){
     9     return 1LL*fac[n]*inv[m]%mod*inv[n-m]%mod;
    10 }
    11 int pow(int n,int m){
    12     int s=n,ans=1;
    13     while (m){
    14         if (m&1)ans=1LL*ans*s%mod;
    15         s=1LL*s*s%mod;
    16         m>>=1; 
    17     }
    18     return ans;
    19 }
    20 int get_f(int x){
    21     int s=1,ans=0;
    22     for(int i=0;i<k;i++){
    23         ans=(ans+1LL*s*a[i])%mod;
    24         s=1LL*s*x%mod;
    25     }
    26     return ans;
    27 }
    28 void dfs(int l,int lst,int p){
    29     if (l>=n)return;
    30     if (s[l]=='0'){
    31         dfs(l+1,lst,p);
    32         return;
    33     }
    34     dfs(l+1,(lst+mi[n-l-1])%mod,(p^1));
    35     if (n-l-1<k)
    36         for(int i=0;i<k;i++){
    37             int s=1;
    38             for(int j=i;j>=0;j--){
    39                 ans=(ans+mod-1LL*a[i]*c(i,j)%mod*s%mod*(f[j][n-l-1][(p^1)]+mod-f[j][n-l-1][p])%mod)%mod;
    40                 s=1LL*s*lst%mod;
    41             }
    42         }
    43 } 
    44 int main(){
    45     mi[0]=1;
    46     for(int i=1;i<N;i++)mi[i]=2*mi[i-1]%mod;
    47     fac[0]=inv[0]=inv[1]=1;
    48     for(int i=1;i<K;i++)fac[i]=1LL*fac[i-1]*i%mod;
    49     for(int i=2;i<K;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
    50     for(int i=1;i<K;i++)inv[i]=1LL*inv[i-1]*inv[i]%mod;
    51     scanf("%s%d",s,&k);
    52     n=strlen(s);
    53     for(int i=0;i<k;i++)scanf("%d",&a[i]);
    54     int nn=mod-1;
    55     for(int i=0;i<n;i++)
    56         if (s[i]=='1')nn=(nn+mi[n-i-1])%mod;
    57     for(int i=0;i<=k;i++){
    58         x[i]=i;
    59         y[i]=get_f(i);
    60         if (i)y[i]=(y[i]+y[i-1])%mod;
    61     }
    62     for(int i=0;i<=k;i++){
    63         int s=y[i];
    64         for(int j=0;j<=k;j++)
    65             if (j!=i)s=1LL*s*(nn-x[j]+mod)%mod*pow((x[i]-x[j]+mod)%mod,mod-2)%mod;
    66         ans=(ans+s)%mod;
    67     }
    68     f[0][0][0]=1;
    69     for(int i=0;i<k;i++)
    70         for(int j=1;j<k;j++){
    71             for(int p=0;p<2;p++){
    72                 f[i][j][p]=f[i][j-1][p];
    73                 for(int t=0;t<=i;t++)f[i][j][p]=(f[i][j][p]+1LL*c(i,t)*pow(2,(j-1)*(i-t))%mod*f[t][j-1][p^1])%mod;
    74             }
    75             //i<j则S[i][j][0]=S[i][j][1] 
    76             //if (S[i][j][0]!=S[i][j][1])printf("%d %d
    ",i,j);
    77         }
    78     dfs(0,0,1);
    79     ans=1LL*ans*(mod+1)/2%mod;
    80     printf("%d",ans);
    81     return 0;
    82 } 
    View Code
  • 相关阅读:
    刘翔那点事
    网站建站模板
    搞笑!from 饮水思源
    我de虚拟经济学系列第一章 经济危机拼命建桥
    IT民工系列——c#操作Microsoft IE,实现自动登录吧!
    商业智能的发展及其应用
    我de虚拟经济学系列第三章 常见的致富之路
    IT民工系列——c#操作EditGrid,自己做一个在线Excel数据库吧!
    Asp.net下的Singleton模式
    asp.net 控件功能小结
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14588370.html
Copyright © 2020-2023  润新知