码迷,mamicode.com
首页 > 其他好文 > 详细

UESTC_Dividing Numbers CDOJ 1156

时间:2015-06-26 21:06:55      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:

Dividing Numbers

Time Limit: 9000/3000MS (Java/Others)     Memory Limit: 262144/262144KB (Java/Others)
 

Given an integer N (1N1013) and K (1K100) co-prime numbers P1P2...Pk, which are less than 1000. Please tell me how many integers in range [1,N] satisfied that none of a number in P1P2...Pk can divide it.

Input

The first line contains two integers N (1N1013) and K (1K100).

The second line contains K numbers P1P2...Pk. It is guaranteed that 2Pi1000.

It is guaranteed that the given K numbers are pairwise co-prime.

Output

Output an integer representing the number of integers in range [1,N] satisfied the condition.

Sample input and output

Sample InputSample Output
20 3
2 3 5
6
50 2
15 8
41

Source

2015 UESTC ACM Summer Training Team Selection (4)
 
结题报告:
注意到题目中的条件,两两互质,这是关键,即gcd( a , b ) = 1 , a, b ∈ array[p]
那么解决这道题的关键就在于重复数字的问题,例如 N = 105 ,  P = 3 , 5 , 那么15 , 30 , 45 .... 这几个数我们就必须保证只能删掉一次
 
我们令 F( i , j ) 表示范围[ 1 , i ] , 不能被P[0] , P[1] ..... P[j] 整除的数的个数
转移方程:
 F ( i , j ) = F( i , j - 1 ) - F( i / p[j] , j - 1 )
转移方程的解释:
我们仅仅考虑P【j】这个数,能够被整数它的肯定是(1,2,3.... i / P[j] ) ,这些数很可能在以后(往前转移)经被筛过了,所以我们需要减去
反正过来想:
【1,N】之间不能被P【0】 -> P【j】 整数的数的数量 = 【1,N】之间不能被P【0】 -> P【j-1】 整除的数 - 【1,N】之间P【j】的因子数目(同时保证这些因子数目不是前面P【0】 -> P【j-1】 任何一个数的因子)
接下来的问题就是搜索了
因为N的范围很大,所以我们在小范围内使用记忆化搜索,大范围上用dfs即可
 
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#define pb push_back
#define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
#define local freopen("in.txt","r",stdin)

using namespace std;
const int maxn = 5e4;

long long n;
int k , p[105];
long long f[maxn][105];

long long dfs(long long x,int y)
{
   if (y == -1) return x;
   if (x < maxn)
    {
        if (f[x][y] != -1) return f[x][y];
        return f[x][y] = dfs(x,y-1) - dfs(x/p[y],y-1);
    }
   else
    return dfs(x,y-1) - dfs(x/p[y],y-1);
}

int main(int argc,char *argv[])
{
  scanf("%lld%d",&n,&k);
  memset(f,-1,sizeof(f));
  for(int i = 0 ; i < k ; ++ i) scanf("%d",&p[i]);
  sort(p,p+k);
  printf("%lld\n",dfs(n,k-1));
  return 0;
}

 

UESTC_Dividing Numbers CDOJ 1156

标签:

原文地址:http://www.cnblogs.com/Xiper/p/4603147.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!