Ultraviolet A 4683
This question refers to a set with a maximum of 12 elements. Find the nth number that can only be divided by one of the sets and only one number. (N <= 10 ^ 15 ).
I did this by using the refresh principle. First, we will accumulate the number of elements that can be divisible by each number. Of course, there will be duplicates. If a number is composed of two numbers in a set, it must be an integer multiple of all the numbers minus two times because it is the common number of the two numbers, when a certain number is three of them, it must also be two of them. In this way, C [k] [2] is reduced, and the number must be added. And so on.
The N number is required. The answer is 10 ^ 15 at the maximum. I divide the number by 10 ^ 15. If the number of matching conditions in [1, m] is res, if res> = N, high = mid-1; otherwise, low = Mid + 1.
But I have not passed the code, no limit to TLE .. The code will be posted here first, hoping that the passing experts will give you some advice.
#include <stdio.h>#include <iostream>#include <map>#include <set>#include <bitset>#include <list>#include <stack>#include <vector>#include <math.h>#include <string.h>#include <queue>#include <string>#include <stdlib.h>#include <algorithm>//#define long long __int64//#define LL long long#define eps 1e-9#define PI acos(-1.0)//typedef __int64 LL;using namespace std;const long long Max = 1000000000000000;int k;long long n;int a[15];long long C[15][15];long long gcd(long long a, long long b){ if(b == 0) return a; return gcd(b,a%b);}long long lcm(long long a, long long b){ return a/gcd(a,b)*b;}void init(){ memset(C,0,sizeof(C)); for(int i = 1; i <= 12; i++) { for(int j = 0; j <= i; j++) { if(j == 0 || j == i) C[i][j] = 1; else if(j == 1) C[i][j] = i; else C[i][j] = C[i-1][j-1] + C[i-1][j]; } }}long long cal(long long m){ long long ans = 0; for(int i = 1; i < (1<<k); i++) { int cnt = 0; long long mul = 1; for(int j = 0; j < k; j++) { if(i&(1<<j)) { cnt++; mul = lcm(mul,a[j]); } } if(cnt&1) ans += C[k][cnt-1]*(m/mul); else ans -= cnt*(m/mul); } return ans;}int main(){ int test; init(); scanf("%d",&test); while(test--) { scanf("%d %I64d",&k,&n); for(int i = 0; i < k; i++) { scanf("%d",&a[i]); } long long low = 0,high = Max; while(low <= high) { long long mid = (low + high)/2; long long res = cal(mid); if(res >= n) high = mid-1; else low = mid+1; } printf("%I64d\n",low); } return 0;}
Ultraviolet A 4683-find the number