zoukankan      html  css  js  c++  java
  • [NOI Online 2021 提高组] 愤怒的小 N

    又来补之前做的题了。。

    容易发现第(i)关为奖励关卡当且仅当(operatorname{bitcount}(i))为奇数。

    于是考虑暴力dp,(f_{i,j,0/1})([0,2^i))位置中(a/b)关卡编号的(j)次方和。

    [f_{i,j,k}=f_{i-1,j,k}+sum_{l=0}^jinom{j}{l}f_{i-1,l,1-k}2^{(i-1)(j-l)} ]

    因为每次加入最高位(2^i)会导致(operatorname{bitcount})奇偶性翻转,编号统一加(2^i),二项式定理暴力展开即可。

    考虑类似数位DP的东西,对于每个(n)上的(1),假定这是第一个把(1)变成(0)的位置求总和。就是每次要求([s,s+2^i))的答案。

    考场上就想到这了。。然后在个位特判翻了傻逼错误导致暴力写挂,我真是个人才哈哈

    我们要学习noi主斗地大力猜结论的精神,当(i > j)时有(f_{i,j,k}=dfrac{sum_{k=0}^{2^i-1}k^j}{2})

    对于(i le K)使用上述暴力DP,(i > K)用上述定理插值求解

    #include<bits/stdc++.h>
    using namespace std;
    #define fp(i,l,r) for(register int (i)=(l);(i)<=(r);++(i))
    #define fd(i,l,r) for(register int (i)=(l);(i)>=(r);--(i))
    #define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next)
    #define mem(a) memset((a),0,sizeof (a))
    #define O(x) cerr<<#x<<':'<<x<<endl
    #define int long long
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    void wr(int x){
        if(x<0)putchar('-'),x=-x;
        if(x>=10)wr(x/10);
        putchar(x%10+'0');
    }
    const int mod=1e9+7;
    inline void tmod(int &x){x%=mod;}
    inline int qpow(int a,int b){
    	int res=1;a%=mod;
    	for(;b;b>>=1,tmod(a*=a))
    		if(b&1)tmod(res*=a);
    	return res;
    }
    inline int ginv(int x){return qpow(x,mod-2);}
    inline int norm(int x){return (x%mod+mod)%mod;}
    int C[510][510],dp[510][510][2],K,a[510],len,pw2[500010],sum[500010],Y[510];
    char s[500010];
    inline int calc(int x){
    	int ss=0;
    	fp(i,0,K+1){
    		Y[i]=ss;
    		int t=0;
    		fd(j,K,0)tmod(t=t*i+a[j]);
    		tmod(ss+=t);
    	}
    	int ans=0;
    	fp(i,0,K+1){
    		int t=Y[i],p=1;
    		fp(j,0,K+1)if(i!=j){
    			tmod(t*=x-j);tmod(p*=i-j);
    		}
    		tmod(ans+=t*ginv(p));
    	}
    	return ans;
    }
    main(){
        scanf("%s",s);len=strlen(s)-1;reverse(s,s+len+1);
        fp(i,0,len)s[i]-='0';
        K=read()-1;
        fp(i,0,K)a[i]=read();
        pw2[0]=1;fp(i,1,500000)pw2[i]=pw2[i-1]*2%mod;
        fp(i,0,K){
    		C[i][0]=1;
    		fp(j,1,i)tmod(C[i][j]=C[i-1][j]+C[i-1][j-1]);
        }
        fp(j,0,K)dp[0][j][1]=1;dp[0][0][0]=1;
        fp(i,1,K)fp(j,0,K)fp(l,0,1){
            dp[i][j][l]=dp[i-1][j][l];
    		fp(p,0,j)tmod(dp[i][j][l]+=dp[i-1][p][l^1]*C[j][p]%mod*pw2[i*(j-p)]);
        }
        fd(i,len,0)sum[i]=sum[i+1]^s[i];
        int ans=0,t=0;
        fp(i,K+1,len)if(s[i])tmod(t+=pw2[i]);
        fd(i,min(K,len),1)if(s[i]){
        	fp(j,0,K){
        		int p=1;
        		fp(l,0,j){
        			tmod(ans+=p*dp[i-1][j-l][sum[i+1]^1]%mod*C[j][l]%mod*a[j]);
        			tmod(p*=t);
    			}
    		}
    		tmod(t+=pw2[i]);
    	}//枚举第一个没有顶上去的1
        if(s[0]&&(sum[1]&1)){
        	int p=1;
    		fp(j,0,K){
    			tmod(ans+=a[j]*p);
    			tmod(p*=t);
    		}
    	}
    	t=0;
    	fp(i,K+1,len)if(s[i])tmod(t+=pw2[i]);
        printf("%lld
    ",norm(ans+(mod+1)/2*calc(t)));
        return 0;
    }
    
  • 相关阅读:
    [原]Java web学习系列之 Java web开发中的SSH整合(Struts、Spring、Hibernate)(下)
    android中webView焦点以及响应输入发的问题
    Android EditText设置光标位置问题
    [原]Java web学习系列之 Java web开发中的Hibernate结合Servlet做分页
    [原]Java web学习系列之 Java web开发中的Struts整合Hibernate
    [原]Java web学习系列之 Java web开发中的Struts框架结构
    [原]Java web学习系列之 Java web开发中的Spring框架
    [原]Java web学习系列之 Java web开发中的SSH整合(Struts、Spring、Hibernate)(上)
    dhl:使用递归获取N级子目录列表(附数据库结构)
    关于反射中Assembly.Load("程序集").CreateInstance("命名空间.类")与Activator.CreateInstance()方法
  • 原文地址:https://www.cnblogs.com/WinterSpell/p/14934023.html
Copyright © 2011-2022 走看看