zoukankan      html  css  js  c++  java
  • 20191217HNOI 模拟赛 复活石

    题目描述:

     

     分析:

    我也不知道我在干sm,但就是没写出来2333

    枚举 i 的每个质因子 j ,复杂度为n^(3/2)

    为什么我会认为是n^2啊2333

    然后考虑 f ( j )对g ( i )做了多少贡献

    这个值当然与x=i / j有关

    对每个x的质因子分开考虑

    那么设某个因子P的指数为A

    那么对于中途sigma的某一位的值Ik,他们的因子P的指数为Ak

    那么为了满足整除性,我们知道Ak是单调不上升的

    那么就可以用组合数算了。。。

    构造长度为K的不超过Ak的不下降序列的方案数相当于将Ak个有标号小球放入K个编了号的箱子中,箱子可空

    差分一下就看出来了2333

    那么方案数就为C(K+Ak-1,Ak)

    对于x的总方案,就是所有质因子方案数相乘,我们设为W(x)

    所以g ( i ) = sigma( j | i ) f ( j ) * W ( i / j )

    其中W是可以O( n^(3/2) )预处理的

    所以总复杂度为O( n^(3/2) )

    此外题解说有一个神仙卷积法,考场上想过但是为什么不继续想啊

    太菜了,复习复习。。。

    ( f * g )(n) = sigma ( j | i ) f ( j ) *g ( i / j )

    我***考试中这式子都写在纸上了怎么还不会啊2333好菜啊2333

    答案就是( f * I ) (n) ^ k,其中函数I中所有值都为1

    快速卷卷起来不就好啦。。。

    /*龙门粗口*/

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    
    #define maxn 200005
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    
    using namespace std;
    
    inline int getint()
    {
        int num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    int n,K;
    long long f[maxn];
    long long g[maxn];
    int pri[maxn],cnt,np[maxn];
    long long fac[maxn],inv[maxn];
    long long W[maxn];
    
    inline long long C(int p,int q)
    {return fac[p]*inv[q]%MOD*inv[p-q]%MOD;}
    
    inline void init()
    {
        for(int i=2;i<maxn/100;i++)
        {
            if(!np[i])pri[++cnt]=i;
            for(int j=1;j<=cnt&&i*pri[j]<maxn/100;j++)
            {
                np[i*pri[j]]=1;
                if(i%pri[j]==0)break;
            }
        }
        fac[0]=fac[1]=inv[0]=inv[1]=1;
        for(int i=2;i<maxn;i++)fac[i]=fac[i-1]*i%MOD;
        for(int i=2;i<maxn;i++)inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD;
        for(int i=2;i<maxn;i++)inv[i]=inv[i]*inv[i-1]%MOD;
    }
    
    int main()
    {
        int T=getint();
        init();
        while(T--)
        {
            memset(g,0,sizeof g);
            n=getint(),K=getint();
            for(int i=1;i<=n;i++)
            {
                int tmp=i;W[i]=1;
                for(int j=1;j<=cnt&&pri[j]<=tmp;j++)
                    if(tmp%pri[j]==0)
                    {
                        int cur=0;
                        while(tmp%pri[j]==0)tmp/=pri[j],cur++;
                        (W[i]*=C(K+cur-1,cur))%=MOD;
                    }
                if(tmp>1)(W[i]*=K)%=MOD;
            }
            for(int i=1;i<=n;i++)f[i]=getint();
            for(int i=1;i<=n;i++)for(int j=1;j*j<=i;j++)
                if(i%j==0)
                {
                    (g[i]+=f[j]*W[i/j])%=MOD;
                    if(j*j!=i)(g[i]+=f[i/j]*W[j])%=MOD;
                }
            for(int i=1;i<=n;i++)printf("%lld%c",g[i],i==n?'
    ':' ');
        }
    }
    View Code

  • 相关阅读:
    学习也好,科研也罢,都有内在规律。任何事物,只消抓住规律,就等于牵住牛鼻子
    赵伟国:陆资无法进入台湾紫光要到WTO控告(芯片是为了经济安全,高通找的人不是很聪明)
    小米新旗舰“翻车” 冲击中高端凸显品控短板(小米的缺点还真不少:电商、性价比、爆款、粉丝经济,说到底也都只是商业上的创新)
    WinRarHelper帮助类
    Window7下安装Ubuntu 14.04 64bit
    Kafka基本原理
    Abot爬虫和visjs
    CLR垃圾回收的设计
    NET Core全新的配置管理
    Github Atom
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12056747.html
Copyright © 2011-2022 走看看