zoukankan      html  css  js  c++  java
  • HDOJ7060 Separated Number

    题目链接

    题意分析

    考试的时候想到了按位分析 但是由于计算公式过于麻烦 所以就咕了

    现在考虑一下按位分析怎么做

    我们对于当前第\(i\)位可以做的贡献

    假设分割之后它处在第\(j\)位上 那么他的贡献就是

    \[d*10^j*num \]

    \(d\)表示第\(i\)位的数字 而\(num\)表示这样之后的划分方案数

    所以接下来我们的任务就是如何计算\(num\)

    \(i+j<n\)

    如果\(i+j<n\) 的话 那么由于我们最后最多划分成\(k\)段 所以考虑插板法 答案就是

    \[\sum_{m=0}^{k-2}C_{n-j-2}^{m} \]

    \(i+j=n\)

    如果\(i+j=n\) 的话 那么由于我们最后最多划分成\(k\)段 所以考虑插板法 答案就是

    \[\sum_{m=0}^{k-1}C_{n-j-1}^{m} \]

    对于\(i+j=n\) 我们可以直接计算入答案中

    而对于\(i+j<n\) 我们可以采用倒序的方式不断累加 从而计算

    \[\sum_{j=0}^{n-i-1}num=\sum_{j=0}^{n-i-1}\sum_{m=0}^{k-2}C_{n-j-2}^{m} \]

    那么关键问题就是如何计算\(\sum_{m=0}^{k-2}C_{n-j-2}^{m}\)以及\(\sum_{m=0}^{k-1}C_{n-j-1}^{m}\)

    我们发现对应的格式是\(\sum_{i=0}^bC_a^i\)

    所以 令

    \[F(a,b)=\sum_{i=0}^bC_a^i \]

    同时 ,由于

    \[C_{n+1}^m=C_{n}^m+C_{n}^{m-1} \]

    \[∴2F(a,b)=2C_a^0+2C_a^1+...+2C_a^b=C_a^0+C_{a+1}^1+...+C_{a+1}^{b}+C_{a}^{b}=C_{a+1}^0+C_{a+1}^1+...+C_{a+1}^{b}+C_{a}^{b}=F(a+1,b)+C_{a}^{b} \]

    所以我们可以得到一个线性的递推公式出来

    \[F(a,b)=2F(a-1,b)-C_{a-1}^{b} \]

    这样的话就可以计算了

    CODE:

    #include<bits/stdc++.h>
    #define M 1000611
    using namespace std;
    const long long mod=998244353;
    int T,n,k;
    char s[M];
    long long ans,sum;
    long long Pow[M],fac[M],inv[M];
    long long Fa[M],Fb[M];
    long long qpow(long long x,long long y)
    {long long tmp=1;for(;y;y>>=1,x=x*x%mod) if(y&1) tmp=tmp*x%mod;return tmp;}
    long long C(int x,int y)
    {
    	if(x<y) return 0;
    	else return (fac[x]*inv[x-y]%mod)*inv[y]%mod;
    }
    int main()
    {
    //	freopen("data.in","r",stdin);	
    	scanf("%d",&T);
    	Pow[0]=fac[0]=inv[0]=1;
    	for(int i=1;i<=1000000;++i) Pow[i]=Pow[i-1]*10%mod;
    	for(int i=1;i<=1000000;++i) fac[i]=fac[i-1]*i%mod;
    	inv[1000000]=qpow(fac[1000000],mod-2);
    	for(int i=999999;i;--i) inv[i]=inv[i+1]*(i+1)%mod;
    	
    	while(T--)
    	{
    		scanf("%d%s",&k,s+1);n=strlen(s+1);
    		sum=0;ans=0;
    		Fa[0]=1;Fb[0]=(k>=2 ? 1:0); 
    		for(int i=1;i<=n;++i)
    		{
    			Fa[i]=(2*Fa[i-1]%mod-C(i-1,k-1)+mod)%mod;
    			Fb[i]=(2*Fb[i-1]%mod-C(i-1,k-2)+mod)%mod;
    		}
    //		for(int i=1;i<=n;++i) printf("%lld%c",Fa[i],(i==n ? '\n':' '));
    //		for(int i=1;i<=n;++i) printf("%lld%c",Fb[i],(i==n ? '\n':' '));
    		for(int i=n;i;--i)
    		{
    			if(i<n) sum=(sum+(Pow[n-i-1]*Fb[i-1]%mod))%mod;
    			ans=(ans+((Pow[n-i]*Fa[i-1]%mod+sum)%mod)*(s[i]-'0')%mod)%mod;
    		}
    		printf("%lld\n",ans);
    	} 
    	return 0;
    }
    
  • 相关阅读:
    HTML
    python io
    python 线程进程
    python socket
    python 面向对象2
    python 面向对象
    python hashlib模块
    python configparser模块
    python logging模块
    数组去重方法汇总
  • 原文地址:https://www.cnblogs.com/tcswuzb/p/15138537.html
Copyright © 2011-2022 走看看