• [luogu2822][组合数问题]


    题目链接

    题解:

    对于上面和下面的式子进行分解质因数,然后看看上面的质因数个数减去下面的质因数个数能不能达到k的质因数的要求即可。
    分解质因数的时候用对于阶乘分解质因数的常用方法:比如要求1999!中能分解出多少个5,那么就把1999不断的除以5,并且把得到的数相加即可。原因显然。
    但是上面方法的复杂度是nnt,明显tle,考虑优化。发现当k固定之后,对于每个n和m是固定的,并且似乎是可以转移的。所以考虑预处理。
    用c[i][j]表示(C_i^j)是不是符合要求。用g[i][j]表示当m为j,n从j到max满足条件的数量。f[i][j]表示n为1到i,m为1到j时满足条件的数量。
    然后只要考虑出f[i][j]的转移即可,显然f[i][j]=f[i][j-1]+g[i][j]
    然后只要O(1)查询即可,懒得现将询问读入再预处理,所以前面的预处理全都是到2000的。

    代码:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int N=2000+10;
    int t,n,m,k,pre[N][10];
    int sushu[10]={0,2,3,5,7,11,13,17,19};
    int ksushu[10],kjs[10];
    void fenk()
    {
    	for(int i=1;i<=8;++i)
    	{
    		if(!k) break;
    		while(k%sushu[i]==0)
    		{
    			kjs[i]++;
    			k/=sushu[i];
    		}
    	}
    
    }
    inline void work2(int x)
    {
    	for(int i=1;i<=8;++i)
    	{
    		int xx=x;
    		while(xx)
    		{
    			xx/=sushu[i];
    			pre[x][i]+=xx;
    		}
    	}
    	return;
    
    }
    int g[N][N],f[N][N],c[N][N];
    inline int pd(int x,int y)
    {
        for(int i=1;i<=8;++i)
           	if(pre[x][i]-pre[y][i]-pre[x-y][i]<kjs[i]) return 0;
        return 1;
    }
    inline int ps(int x)
    {
    	if(x==2||x==3) return 1;
    	if(x%6!=5&&x%6!=1) return 0;
    	for(int i=5;i*i<=x;i+=6)
    		if(x%(i+2)==0||x%i==0) return 0;
    	return 1;
    }
    int main()
    {
        scanf("%d%d",&t,&k);
        	fenk();
        for(int i=2;i<=2000;++i)
        	work2(i);
        for(int i=1;i<=2000;++i)
            for(int j=1;j<=i;++j)
                if(pd(i,j)) 
                	c[i][j]=1;
        for(int j=1;j<=2000;++j)
            for(int i=j;i<=2000;++i)
                g[i][j]=g[i-1][j]+c[i][j];
        for(int i=1;i<=2000;++i)
            for(int j=1;j<=i;++j)
                f[i][j]=f[i][j-1]+g[i][j];
        int x,y;
        while(t--)
        {
    
            scanf("%d%d",&x,&y);
            printf("%d
    ",f[x][min(x,y)]);
        }
        return 0;
    }
    
  • 相关阅读:
    Python使用QRCode模块生成二维码
    C++ STL中允许重复key的multimap
    C++ STL中Map的按Value排序
    C++ STL中Map的按Key排序
    C++ String和其他类型互换
    android studio
    加快android studio 编译速度(已更新至Android Studio 3.3.1)
    解决Installation failed with message Failed to finalize session : INSTALL_FAILED_INVALID_APK的问题
    Android 自定义Dialog 去除阴影
    FFmpeg(14)-使用NDK、C++完成EGL,display, surface, context的配置和初始化
  • 原文地址:https://www.cnblogs.com/wxyww/p/9535076.html
Copyright © 2020-2023  润新知