LightOJ1298 One Theorem, One Year(DP + 欧拉函数性质)
题目
Source
http://www.lightoj.com/volume_showproblem.php?problem=1298
Description
A number is Almost-K-Prime if it has exactly K prime numbers (not necessarily distinct) in its prime factorization. For example, 12 = 2 * 2 * 3 is an Almost-3-Prime and 32 = 2 * 2 * 2 * 2 * 2 is an Almost-5-Prime number. A number X is called Almost-K-First-P-Prime if it satisfies the following criterions:
1. X is an Almost-K-Prime and
2. X has all and only the first P (P ≤ K) primes in its prime factorization.
For example, if K=3 and P=2, the numbers 18 = 2 * 3 * 3 and 12 = 2 * 2 * 3 satisfy the above criterions. And 630 = 2 * 3 * 3 * 5 * 7 is an example of Almost-5-First-4-Pime.
For a given K and P, your task is to calculate the summation of Φ(X) for all integers X such that X is an Almost-K-First-P-Prime.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case starts with a line containing two integers K (1 ≤ K ≤ 500) and P (1 ≤ P ≤ K).
Output
For each case, print the case number and the result modulo 1000000007.
Sample Input
3
3 2
5 4
99 45
Sample Output
Case 1: 10
Case 2: 816
Case 3: 49939643
分析
题目大概说,定义,一个数为Almost-K-First-P-Prime当且仅当这个数由K个质因子组成,且这K个质因子包含且仅包含于前P个质数。给定k和p,求Σphi(AkFpP)。
首先要知道欧拉函数这几个性质:
- φ(p)=p-1(p是质数)
- φ(p*a)=(p-1)*φ(a)(p是质数且p不能整除a)
- φ(p*a)=p*φ(a)(p是质数且p|a)
然后,可以考虑用DP来解,利用上面的性质去转移。
一开始我这么想的,首先由于k个质因子中那p个是一定要有的,先把它们固定下来,即∏prime[1...p],其phi值为∏(prime[1...p]-1)。然后还剩下k-p个质因子要确定,有p个质因子可以选择,这其实就是完全背包问题了:p种物品体积都为1选了之后价值*prime[i],背包容量k-p,问所有选择方案的价值和。
不过这样会TLE的,数据有10000组,通过可以枚举p把所有情况预处理出来,O(P2K)的时间复杂度,可能会超时,不过已经爆内存了。
事实上还有更直接的预处理方式:
- dp[i][j]表示Σphi(Almost-i-First-j-Prime)
考虑这么转移:
- 如果prime[j]只出现一次,那么就是从dp[i-1][j-1](这个状态prime[j]不会出现,出现的是前j-1个质数)通过第i个质因子选择prime[j]转移:dp[i][j]+=dp[i-1][j-1]*(prime[j]-1)
- 如果prime[j]出现多于一次,那么就是从dp[i-1][j](这个状态prime[j]至少出现一次,再加上一次就大于1次了)转移了:dp[i][j]+=dp[i-1][j]*prime[j]
时间复杂度就是O(PK)
其实这种转移的分析方式觉得挺强的,分成等于1、大于等于1,这两个能分别求出来且互补的子问题。和排队购票那个经典题的转移一样。
下面是那两个算法的代码实现。
代码
O(P2K)
#include<cstdio>
#include<cstring>
using namespace std; int prime[555]; bool is_prime(int n){
for(long long i=2; i*i<=n; ++i){
if(n%i==0) return 0;
}
return 1;
} long long d[501][501][500]; void init(){
int n=0;
for(int i=2; n!=500; ++i){
if(is_prime(i)){
prime[++n]=i;
}
}
for(int p=1; p<=500; ++p){
d[p][0][0]=1;
for(int i=1; i<=p; ++i){
d[p][0][0]*=prime[i]-1;
d[p][0][0]%=1000000007;
}
for(int i=1; i<=p; ++i){
for(int j=0; j<500; ++j){
if(j) d[p][i][j]=d[p][i-1][j]+d[p][i][j-1]*prime[i];
else d[p][i][j]=d[p][i-1][j];
d[p][i][j]%=1000000007;
}
}
}
} int main(){
init();
int t,k,p;
scanf("%d",&t);
for(int cse=1; cse<=t; ++cse){
scanf("%d%d",&k,&p);
printf("Case %d: %lld\n",cse,d[p][p][k-p]);
}
return 0;
}
O(PK)
#include<cstdio>
#include<cstring>
using namespace std; int prime[555]; bool is_prime(int n){
for(long long i=2; i*i<=n; ++i){
if(n%i==0) return 0;
}
return 1;
} long long d[555][555]; void init(){
int n=0;
for(int i=2; n!=500; ++i){
if(is_prime(i)){
prime[++n]=i;
}
}
d[0][0]=1;
for(int i=1; i<=500; ++i){
for(int j=1; j<=i; ++j){
d[i][j]+=d[i-1][j-1]*(prime[j]-1);
if(i-1>=j) d[i][j]+=d[i-1][j]*prime[j];
d[i][j]%=1000000007;
}
}
} int main(){
init();
int t,k,p;
scanf("%d",&t);
for(int cse=1; cse<=t; ++cse){
scanf("%d%d",&k,&p);
printf("Case %d: %lld\n",cse,d[k][p]);
}
return 0;
}
LightOJ1298 One Theorem, One Year(DP + 欧拉函数性质)的更多相关文章
- lightOJ1370 欧拉函数性质
D - (例题)欧拉函数性质 Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:32768KB ...
- HDU 6390 GuGuFishtion(莫比乌斯反演 + 欧拉函数性质 + 积性函数)题解
题意: 给定\(n,m,p\),求 \[\sum_{a=1}^n\sum_{b=1}^m\frac{\varphi(ab)}{\varphi(a)\varphi(b)}\mod p \] 思路: 由欧 ...
- poj-2478 Farey Sequence(dp,欧拉函数)
题目链接: Farey Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14230 Accepted: ...
- HDU2824【欧拉函数性质】
思路: 打表. 利用公式. 类似素数打表一样. #include<bits/stdc++.h> using namespace std; const int N=3e6+10; bool ...
- HDOJ 1787 GCD Again(欧拉函数)
GCD Again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Codeforces Round #538 (Div. 2) F 欧拉函数 + 区间修改线段树
https://codeforces.com/contest/1114/problem/F 欧拉函数 + 区间更新线段树 题意 对一个序列(n<=4e5,a[i]<=300)两种操作: 1 ...
- hdu2824 The Euler function(欧拉函数个数)
版权声明:本文为博主原创文章,未经博主同意不得转载. vasttian https://blog.csdn.net/u012860063/article/details/36426357 题目链接:h ...
- LightOJ 1370- Bi-shoe and Phi-shoe (欧拉函数)
题目大意:一个竹竿长度为p,它的score值就是比p长度小且与且与p互质的数字总数,比如9有1,2,4,5,7,8这六个数那它的score就是6.给你T组数据,每组n个学生,每个学生都有一个幸运数字, ...
- lightoj1370欧拉函数/素数筛
这题有两种解法,1是根据欧拉函数性质:素数的欧拉函数值=素数-1(可根据欧拉定义看出)欧拉函数定义:小于x且与x互质的数的个数 #include<map> #include<set& ...
随机推荐
- [Android Pro] Gradle tip #3-Task顺序
reference to : http://blog.csdn.net/lzyzsd/article/details/46935405 原文链接 我注意到我在使用Gradle的时候遇到的大多数问题都是 ...
- #import、#include、#import<>和#import””的区别
一.#import与#include #import不会引起交叉编译的问题.因为在Objective-C中会存在C/C++和Object-C混编的问题,如果用#include引入头文件,会导致交叉编译 ...
- 谈谈我的编程之路---WAMP(二)
WAMP的一些配置与使用心得(MYSQL) 刚开始接触数据库的时候,我一直认为数据库操作工具和数据库是同一种东西,它们是一体的,后来我才明白,数据库它是一个独立的仓库,用官方点的话来解释 数据库(Da ...
- SVN 操作指南
1.安装 和 使用 2.导入导出 2.错误信息 ① svn不知到这样的主机
- PHP define()的用法
define()函数理解1(着重于作用的理解) define() 函数定义一个常量. 常量的特点: 常量类似变量,不同之处在于:在设定以后,常量的值无法更改常量名,不需要开头的美元符号 ($),作用域 ...
- ASP.NET Web Api 实现数据的分页(转载)
转载地址:http://www.cnblogs.com/fzrain/p/3542608.html 前言 这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的OData本文暂不涉及,但有可能 ...
- ListView优化中ViewHolder要不要定义为static静态内部类?
给学生讲课的时候,发现存在这个问题,下来百度了下,发现很纠结,涉及到了内部类对外部类的引用,静态类的生命周期等java知识,现总结如下: static class ViewHolder { //定义l ...
- Linux 下 Console / 控制台 复制粘贴快捷键
Linux下复制粘贴快捷键 1. 在终端下: 复制命令:Ctrl + Shift + C 组合键. 粘贴命令:Ctrl + Shift + V 组合键. 2. 在控制台下: 复制命令:Ctrl + ...
- Delphi的字符串、PChar和字符数组之间的转换
参考:http://my.oschina.net/kavensu/blog/193719 以下的各种方法都是我在Delphi 6的环境下测试成功的,可能根据你的开发环境.不同的上下文语境……有一些可能 ...
- 【Java EE 学习 21 下】【使用java实现邮件发送、邮件验证】
一.邮件发送 1.邮件发送使用SMTP协议或者IMAP协议,这里使用SMTP协议演示. SMTP协议使用的端口号:25 rfc821详细记载了该协议的相关信息 (1)使用telnet发送邮件(使用12 ...