J Heritage of skywalkert
分析:题意就不累赘了,主要值得mark的点就是:nth_element(b, b + len, b + n) 能把前len小的数找到,同样大的也能找到,并且是
O(n)
O
(
n
)
,因为len位置之前都是比它小的,但是乱序的.
之后敢于猜测,把前20大的数字用nth_element找到,暴力找lcm就ok了.
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const int MAXN = 1e7 + 10;
unsigned x, y, z;
LL b[MAXN];
unsigned tang() {
unsigned t;
x ^= x << 16;
x ^= x >> 5;
x ^= x << 1;
t = x;
x = y;
y = z;
z = t ^ x ^ y;
return z;
}
LL gcd(LL a, LL b) {
return !b ? a : gcd(b, a % b);
}
LL lcm(LL a, LL b) {
return a * b / gcd(a, b);
}
int main() {
int T, p = 1;
scanf("%d", &T);
while(T--) {
int n;
scanf("%d %u %u %u", &n, &x, &y, &z);
for(int i = 0; i < n; ++i) {
b[i] = tang();
}
int len = max(n - 20, 0);
nth_element(b, b + len, b + n);
LL ans = 0;
for(int i = len; i < n; ++i) {
for(int j = i + 1; j < n; ++j) {
ans = max(ans, lcm(b[i], b[j]));
}
}
printf("Case #%d: %llu\n", p++, ans);
}
return 0;
}