• [省选集训2022] 叮叮车


    一、题目

    对于 \(i\in[l,r]\)\({2i\choose i}\) 最多含有的 质因子 \(7\) 的个数 是多少?

    \(l\leq r\leq 10^{10000}\)

    二、解法

    考虑 \({2n\choose n}\) 含有质因数 \(7\) 的个数是:

    \[\sum_{i=0}^{\infty}\lfloor\frac{2n}{7^i}\rfloor-2\lfloor\frac{n}{7^i}\rfloor=\sum_{i=0}^{\infty}[2(n\bmod 7^i)\geq 7^i] \]

    我们先把 \(l,r\) 都转化成 \(7\) 进制,那么如果某个数的后 \(i\) 位乘 \(2\) 可以进位,就说明产生了一个贡献。设 \(dp[i][0/1][0/1][0/1]\) 表示考虑了前 \(i\) 位,是否抵到下界,是否顶到上界,\(2\) 之后一定进位 \(/\) 一定不进位,的最大贡献。

    转移就考虑枚举当前这一位选了什么,然后按照和 \(3\) 的大小关系来分类讨论即可。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int M = 20005;
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int n,m,ans,l[M],r[M],s[M],dp[M][2][2][2];char t[M];
    void upd(int &x,int y) {x=max(x,y);}
    void zxy(int *a)
    {
    	scanf("%s",t+1);m=strlen(t+1);n=0;
    	for(int i=1;i<=m;i++) s[i]=t[i]-'0';
    	reverse(s+1,s+1+m);
    	while(m)
    	{
    		int sum=0;
    		for(int i=m;i>=1;i--)
    			s[i]+=10*sum,sum=s[i]%7,s[i]/=7;
    		a[++n]=sum;
    		while(s[m]==0 && m) m--;
    	}
    }
    int main()
    {
    	freopen("dingdingcar.in","r",stdin);
    	freopen("dingdingcar.out","w",stdout);
    	zxy(l);zxy(r);
    	memset(dp,-0x3f,sizeof dp);
    	dp[n][1][1][0]=0;
    	dp[n][1][1][1]=1;
    	for(int i=n;i>=1;i--) for(int a=0;a<2;a++)
    		for(int b=0;b<2;b++) for(int j=0;j<7;j++)
    		{
    			if((a&&j<l[i]) || (b&&j>r[i])) continue;
    			int A=a&(j==l[i]),B=b&(j==r[i]);
    			if(j<3)
    			{
    				upd(dp[i-1][A][B][0],dp[i][a][b][0]);
    				upd(dp[i-1][A][B][1],dp[i][a][b][0]+1);
    			}
    			if(j==3)
    			{
    				upd(dp[i-1][A][B][0],dp[i][a][b][0]);
    				upd(dp[i-1][A][B][1],dp[i][a][b][1]+1);
    			}
    			if(j>3)
    			{
    				upd(dp[i-1][A][B][0],dp[i][a][b][1]);
    				upd(dp[i-1][A][B][1],dp[i][a][b][1]+1);
    			}
    		}
    	for(int a=0;a<2;a++) for(int b=0;b<2;b++)
    		upd(ans,dp[0][a][b][0]);
    	printf("%d\n",ans);
    }
    
  • 相关阅读:
    centos6 python 安装 sqlite 解决 No module named ‘_sqlite3′
    Python--Virtualenv简明教程
    【centos】 error: command 'gcc' failed with exit status 1
    python3.5学习笔记:linux6.4 安装python3 pip setuptools
    Python的虚拟环境virtualenv
    hdu Robberies
    转载:hdu 动态规划题集
    在Eclipse中配置Tomcat 创建和运行Servlet/JSP
    opengl中层次建模的实现
    shiyan2
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/16110062.html
Copyright © 2020-2023  润新知