Codeforces 893E - Counting Arrays

Posted Wisdom+.+

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 893E - Counting Arrays相关的知识,希望对你有一定的参考价值。

893E - Counting Arrays

思路:质因子分解。

对于每个质因子,假设它有k个,那么求把它分配到y个数上的方案数。

相当于把k个小球分配到y个盒子里的方案数。

这个问题可以用隔板法(插空法)解决,要把一段分成y段,需要y-1个隔板,那么有y-1+k个位置,选y-1个位置为隔板,剩下的都是小球,那么方案数为C(y-1+k,y-1)。

如果全为正数,答案就是所有质因子方案数的积。

但是这道题目可以为负数,那么在这y个数里选偶数个变成负数

答案还要乘以C(y,0)+C(y,2)+C(y,4)+C(y,6)+...                              ③

这个问题是高中排列组合的一个经典问题,

设(1+x)^y=C(y,0)*x^0+C(y,1)*x^1+...+C(y,y-1)*x^(y-1)+C(y,y)*x^y

当x=1时,C(y,0)+C(y,1)+...+C(y,y-1)+C(y,y)=2^y                       ①

当x=-1时,C(y,0)-C(y,1)+C(y,2)-C(y-3)+...=0                             ②

①+②=2*③

③式为2^(y-1)

代码:

By ZhihuiLiu, contest: Educational Codeforces Round 33 (Rated for Div. 2), problem: (E) Counting Arrays, Accepted, #, hack it!

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int MOD=1e9+7;
const int N=1e6+5;
ll fac[2*N];
ll q_pow(ll n,ll k)
{
    ll ans=1;
    while(k)
    {
        if(k&1)ans=(ans*n)%MOD;
        n=(n*n)%MOD;
        k>>=1;
    }
    return ans;
}
void init()
{
    fac[0]=1;
    for(int i=1;i<2*N;i++)fac[i]=(fac[i-1]*i)%MOD;
}
ll C(ll n,ll m)
{
    return (fac[n]*q_pow(fac[m],MOD-2))%MOD*q_pow(fac[n-m],MOD-2)%MOD;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int q,x,y;
    init();
    cin>>q;
    while(q--)
    {
        cin>>x>>y;
        int c=0;
        ll ans=q_pow(2,y-1);
        for(int i=2;i*i<=x;i++)
        {
            if(x%i==0)
            {
                int t=0;
                while(x%i==0)
                {
                    t++;
                    x/=i;
                }
                ans=(ans*C(t+y-1,t))%MOD;
            }
        }
        if(x>1)ans=(ans*y)%MOD;
        cout<<ans<<endl;
    }
    return 0;
}

 

以上是关于Codeforces 893E - Counting Arrays的主要内容,如果未能解决你的问题,请参考以下文章

setInterval的基本用法

排序专题-插入排序

Git-从远程仓库克隆

Linux上case用法

如何使用迭代器嵌套循环?

XQuery:将日期时间与毫秒进行比较