题目链接:http://codeforces.com/problemset/problem/893/E

题意:

  共q组数据(q <= 10^5),每组数据给定x,y(x,y <= 10^6)。

  问你有多少种长度为y,乘积为x的整数数列。(可以有负数)

题解:

  首先考虑数列只有正整数的情况。

  将x分解质因数:x = ∑ a[i]*p[i]

  由于x较大,所以要先用线性筛求出素数,再枚举素数分解质因数。

  那么一个乘积为x的数列可以看做,将x的所有∑ p[i]个质因子,分配到了y个位置上。

  设f(i)表示:将p[i]个质因子a[i],分配到y个位置上的方案数。

  所以乘积为x的数列总数ans = ∏ f(i)。

  其中,f(i)等价于:长度为y,和为p[i]的数列总数。

  由于是多组数据,所以要预处理出对于所有长度的f(i)。

  dp[i][j]表示y = i时,之和为j的数列总数。

  转移:dp[i][j] = ∑ dp[i-1][0 to j]

  用前缀和优化转移,总复杂度O(nlogn)。

  这样就求出了只考虑正整数情况下的数列总数:ans = ∑ dp[y][p[i]]

  然后考虑加负号的情况。

  由于x为正数,所以只能加偶数个负号。

  所以加负号的方案数 = C(y,0) + C(y,2) + C(y,4) + ... + C(y,偶数)

  有一个组合数结论:∑ C(n,偶数) = ∑ C(n,奇数) = 2^(n-1)。

  所以最终ans = ans * (2^(y-1))即为最终答案。

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_X 1000005
#define MAX_P 25
#define SET_X 1000000
#define SET_P 20
#define MOD 1000000007 using namespace std; int x,y,q;
int cnt,tot=;
int p[MAX_P];
int pw[MAX_X];
int prime[MAX_X];
int dp[MAX_X][MAX_P];
int sum[MAX_X][MAX_P];
bool mark[MAX_X]; void cal_dp()
{
memset(dp,,sizeof(dp));
memset(sum,,sizeof(sum));
dp[][]=;
for(int i=;i<=SET_P;i++) sum[][i]=;
for(int i=;i<=SET_X;i++)
{
for(int j=;j<=SET_P;j++)
{
dp[i][j]=sum[i-][j];
sum[i][j]=(sum[i][j-]+dp[i][j])%MOD;
}
}
} void cal_pw()
{
pw[]=;
for(int i=;i<=SET_X;i++) pw[i]=(pw[i-]<<)%MOD;
} void sieve()
{
memset(mark,false,sizeof(mark));
for(int i=;i<=SET_X;i++)
{
if(!mark[i]) prime[++tot]=i;
for(int j=;j<=tot && (long long)i*prime[j]<=SET_X;j++)
{
mark[i*prime[j]]=true;
if(!(i%prime[j])) break;
}
}
} void resolve()
{
int t=x;
cnt=;
memset(p,,sizeof(p));
for(int i=;i<=tot && prime[i]*prime[i]<=x;i++)
{
if(t%prime[i]==)
{
cnt++;
while(t%prime[i]==)
{
t/=prime[i];
p[cnt]++;
}
}
}
if(t!=) p[++cnt]=;
} int cal_ans()
{
resolve();
long long ans=;
for(int i=;i<=cnt;i++) ans=ans*dp[y][p[i]]%MOD;
return ans*pw[y-]%MOD;
} int main()
{
sieve();
cal_dp();
cal_pw();
cin>>q;
while(q--)
{
cin>>x>>y;
cout<<cal_ans()<<endl;
}
}

Codeforces 893E Counting Arrays:dp + 线性筛 + 分解质因数 + 组合数结论的更多相关文章

  1. Codeforces 893E - Counting Arrays

    893E - Counting Arrays 思路:质因子分解. 对于每个质因子,假设它有k个,那么求把它分配到y个数上的方案数. 相当于把k个小球分配到y个盒子里的方案数. 这个问题可以用隔板法(插 ...

  2. Gym 101981J - Prime Game - [数学题][线性筛+分解质因数][2018-2019 ACM-ICPC Asia Nanjing Regional Contest Problem J]

    题目链接:http://codeforces.com/gym/101981/attachments 题意: 令 $mul(l,r) = \prod_{i=l}^{r}a_i$,且 $fac(l,r)$ ...

  3. 【20181027T1】洛阳怀【推结论+线性筛+分解质因数+GCD性质】

    原题:CF402D [错解] 唔,先打个表看看 咦,没有坏质数好像就是质因数个数啊 那有坏质数呢? 好像变负数了 推出错误结论:f(x)=x的质因数个数,如果有个坏质数,就乘上-1 然后乱搞,起码花了 ...

  4. 893E - Counting Arrays

    E. Counting Arrays time limit per test 3 seconds memory limit per test 256 megabytes input standard ...

  5. Codeforces 264B Good Sequences(DP+素数筛)

    题目链接:http://codeforces.com/problemset/problem/264/B 题目大意:给出n个单调递增的数,让你找出最长的好序列,好序列是一种单调递增的并且相邻元素的最大公 ...

  6. 【???】今天上午的考试题——区间dp和字符串/线性筛的综合应用

    T3还没有打出来,就先放两道. ---------------------------------------------------------- T1:密码破译 温温手下的情报部门截获了一封加密信 ...

  7. 【BZOJ-4514】数字配对 最大费用最大流 + 质因数分解 + 二分图 + 贪心 + 线性筛

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 726  Solved: 309[Submit][Status ...

  8. Divisor counting [线性筛积性函数]

    Divisor counting 题目大意:定义f(n)表示整数n的约数个数.给出正整数n,求f(1)+f(2)+...+f(n)的值. 注释:1<=n<=1000,000 想法:我们再次 ...

  9. Codeforces 822D My pretty girl Noora - 线性筛 - 动态规划

    In Pavlopolis University where Noora studies it was decided to hold beauty contest "Miss Pavlop ...

随机推荐

  1. 检验指定路径的文件是否存在ftp服务器中

    import org.apache.commons.net.ftp.FTP;import org.apache.commons.net.ftp.FTPClient;import org.apache. ...

  2. 洛谷 P1640 [SCOI2010]连续攻击问题

    洛谷 一句话题意: 每个武器有两种属性,每种武器只能选择一种属性,从属性1连续递增才算攻击,求最大连续攻击次数. 因为同学告诉我这是二分图最大匹配,自然就往那个方向去想. 那么怎么建图呢? 每个武器只 ...

  3. Python3.6全栈开发实例[016]

    16.电影打分:程序先给出几个目前正在上映的电影列表. 由用户给每个电影投票.最终将该用户投票信息公布出来 lst = ['北京遇上西雅图', '解救吴先生', '美国往事', '西西里的美丽传说'] ...

  4. C#窗口的Load事件与Shown事件的差别

    Load:在第一次显示窗口前发生. <pre name="code" class="csharp"> private void Form1_Load ...

  5. Python 学习之旅

    流程图 第一章  Python简介 第二章  Python基础 第三章  流程控制 第四章  字符编码 第五章  文件处理 第六章  函数 第七章 模块与包 第八章 面向对象 第九章 异常处理 第十章 ...

  6. 小程序发送 request请求失败 提示不在合法域名列表中的解决方法

    可以在小程序开发工具中设置不校验域名.

  7. Java基础—序列化与反序列化(转载)

    转载自: Java序列化与反序列化 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化 ...

  8. 自定义gradle plugin

    最近开始接触gradle 正好有个需求apidoc

  9. 4.1 使用STM32控制MC20拨打电话

    需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...

  10. Android开发之旅-获取地理位置的经度和纬度

    在Android应用程序中,可以使用LocationManager来获取移动设备所在的地理位置信息.看如下实例:新建android应用程序TestLocation. 1.activity_main.x ...