时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
skywalkert, the new legend of Beihang University ACM-ICPC Team, retired this year leaving a group of newbies again.
Rumor has it that he left a heritage when he left, and only the one who has at least 0.1% IQ(Intelligence Quotient) of his can obtain it.
To prove you have at least 0.1% IQ of skywalkert, you have to solve the following problem:
Given n positive integers, for all (i, j) where 1 ≤ i, j ≤ n and i ≠ j, output the maximum value among . means the Lowest Common Multiple.
输入描述:
The input starts with one line containing exactly one integer t which is the number of test cases. (1 ≤ t ≤ 50) For each test case, the first line contains four integers n, A, B, C. (2 ≤ n ≤ 107, A, B, C are randomly selected in unsigned 32 bits integer range)
The n integers are obtained by calling the following function n times, the i-th result of which is ai, and we ensure all ai > 0. Please notice that for each test case x, y and z should be reset before being called.
No more than 5 cases have n greater than 2 x 106.
输出描述:
For each test case, output "Case #x: y" in one line (without quotes), where x is the test case number (starting from 1) and y is the maximum lcm.
示例1
输入
2 2 1 2 3 5 3 4 8
输出
Case #1: 68516050958 Case #2: 5751374352923604426
题意:给出一个N和A,B,C,求通过上面的函数带入A,B,C后获得的N个数中任意2个数的最小公倍数LCM的最大值.
题解:由于上面的函数得到的数基本上可以说是很随机了,由欧拉等定理可以知道(出题人说的)对于任意2个随机数互质的概率是,已经非常高了,那么对于1e7个数来说,我们取出前100大的数求LCM得到的最大值基本上就可以认为是1e7个数任意2个数LCM的最大值了(大胆猜想hhh,比赛就是这么写过的,最后测评姬帮我们证明了~)
那么剩下的就是通过STL的priority_queue来实现存放100大的数据,不过由于出题人好玩,故意卡该步骤(若是没有写好------无脑push和pop,那么就需要多几次O(logn)的操作,那么只能TLE了).
代码如下:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<queue>
#include<queue>
using namespace std;
const int maxn = 1e5 + 10;
#define ull unsigned long long
struct cmp{
bool operator ()(ull x,ull y){
return x > y;
}
};
priority_queue<ull, vector<ull>, cmp>q;
ull a[150];
unsigned int x, y, z;
ull Rand() {
unsigned int t;
x ^= x << 16;
x ^= x >> 5;
x ^= x << 1;
t = x;
x = y;
y = z;
z = t^x^y;
return (ull)z;
}
ull gcd(ull x, ull y) {
return y == 0 ? x : gcd(y, x%y);
}
ull lcm(int x, int y) {
return a[x] / gcd(a[x], a[y])*a[y];
}
int main()
{
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++) {
int n;
cin >> n >> x >> y >> z;
for (int i = 0; i < n; i++) {
ull tmp = Rand();
if (i < 100)q.push(tmp); //一点小优化
else if (tmp > q.top()) {
q.pop();
q.push(tmp);
}
}
int top = 0;
while (!q.empty()) {
a[top++] = q.top();
q.pop();
}
ull ans = 0;
for (int i = 0; i < top; i++)
for (int j = i + 1; j < top; j++)
ans = max(ans, lcm(i, j));
cout << "Case #" << t << ": " << ans << endl;
}
return 0;
}