实测是代码中分割线之前的超时,基数排序跑了 7s,106 到 110 行跑了 1s 多,卡不出来了,求助。
先放代码
#include<bits/stdc++.h>
#define MAXN 30000001
using namespace std;
typedef unsigned long long ull;
typedef __int128_t llt;
const int N = 3e7 + 10;
int n, A, B, C, u[N], v[N], w[N];
ull Rand(ull &k1, ull &k2){
ull k3 = k1, k4 = k2;
k1 = k4;
k3 ^= (k3 << 23);
k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);
return k2 + k4;
}
void GetData(){
ull x, y;
scanf("%d%d%d%d%llu%llu",&n,&A,&B,&C,&x,&y);
for (int i = 1; i <= n; i++) {
u[i] = Rand(x, y) % A + 1;
v[i] = Rand(x, y) % B + 1;
w[i] = Rand(x, y) % C + 1;
if (Rand(x, y) % 3 == 0) u[i] = A;
if (Rand(x, y) % 3 == 0) v[i] = B;
if ((u[i] != A) && (v[i] != B)) w[i] = C;
}
}
void print(llt x){
if(x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
namespace maybe_ok{
struct node{ int x, y; };
bool operator > (node a, node b){ return a.x == b.x ? a.y > b.y : a.x > b.x; }
bool operator < (node a, node b){ return a.x == b.x ? a.y < b.y : a.x < b.x; }
vector<node> a[3];
llt ans;
vector<node> radix_sort(int n, vector<node> v){
node *b = new node[n], *a = new node[n];
for(int i = 0; i < n; i++) a[i] = v[i];
int *cnt = new int[1 << 16];
int mask = (1 << 16) - 1;
node *x = a, *y = b;
for(int i = 0; i < 32; i += 16){
for(int j = 0; j < (1 << 16); j++) cnt[j] = 0;
for(int j = 0; j < n; j++) ++cnt[x[j].y >> i & mask];
for(int sum = 0, j = 0; j < (1 << 16); j++){
sum += cnt[j]; cnt[j] = sum - cnt[j];
}
for(int j = 0; j < n; j++) y[cnt[x[j].y >> i & mask]++] = x[j];
swap(x, y);
}
for(int i = 0; i < 32; i += 16){
for(int j = 0; j < (1 << 16); j++) cnt[j] = 0;
for(int j = 0; j < n; j++) ++cnt[x[j].x >> i & mask];
for(int sum = 0, j = 0; j < (1 << 16); j++){
sum += cnt[j]; cnt[j] = sum - cnt[j];
}
for(int j = 0; j < n; j++) y[cnt[x[j].x >> i & mask]++] = x[j];
swap(x, y);
}
for(int i = 0; i < n; i++) v[i] = a[i];
delete[] cnt; delete[] b; delete[] a;
return v;
}
void my_unique(int op){
vector<node> b;
int siz = a[op].size();
// printf("%d\n",siz);
// int t1 = clock();
a[op] = radix_sort(siz, a[op]);
// int t2 = clock();
// printf("%lg\n",(double)(t2-t1)/CLOCKS_PER_SEC);
// printf("*\n");
for(int i = 0, j = 0; i < siz; i = j){
while(j < siz && a[op][j].x == a[op][i].x) j++;
b.push_back(a[op][j - 1]);
}
siz = b.size(); a[op].clear();
for(int i = 0; i < siz; i++){
while(!a[op].empty() && a[op].back().y < b[i].y) a[op].pop_back();
a[op].push_back(b[i]);
}
}
llt work(int p, int k){
int siz = a[p].size();
if(siz == 0) return 0;
llt res = 0;
res += (llt)a[p][0].y * a[p][0].x * k;
for(int i = 1; i < siz; i++){
res += (llt)a[p][i].y * (a[p][i].x - a[p][i - 1].x) * k;
}
return res;
}
llt corss(int l1, int r1, int l2, int r2){
return max(min(r1, r2) - max(l1, l2), 0);
}
void main(){
// for(int i = 1; i <= n; i++){
// if(u[i] == A && v[i] == B && w[i] == C){
// print((llt)A * B * C);
// printf("\n");
// return ;
// }
// }
// int t1 = clock();
for(int i = 1; i <= n; i++){
if(u[i] == A) a[0].push_back((node){v[i], w[i]});
else if(v[i] == B) a[1].push_back((node){u[i], w[i]});
else if(w[i] == C) a[2].push_back((node){u[i], v[i]});
}
// int t2 = clock();
// printf("%lg\n",(double)(t2-t1)/CLOCKS_PER_SEC);
my_unique(0); my_unique(1); my_unique(2);
// t2 = clock();
// printf("%lg\n",(double)(t2-t1)/CLOCKS_PER_SEC);
//---------------------------- 分割线 ----------------------------
ans += work(0, A); ans += work(1, B); ans += work(2, C);
int siza = a[0].size(), sizb = a[1].size(), sizc = a[2].size();
for(int i = 0; i < siza; i++){
for(int j = 0; j < sizb; j++){
ans -= (llt)(a[1][j].x - (j == 0 ? 0 : a[1][j - 1].x)) * (llt)(a[0][i].x - (i == 0 ? 0 : a[0][i - 1].x)) * corss(0, a[0][i].y, 0, a[1][j].y);
}
}
for(int i = 0; i < sizb; i++){
for(int j = 0; j < sizc; j++){
ans -= (llt)corss(i == 0 ? 0 : a[1][i - 1].x, a[1][i].x, j == 0 ? 0 : a[2][j - 1].x, a[2][j].x) * (llt)a[2][j].y * (llt)a[1][i].y;
}
}
for(int i = 0; i < siza; i++){
for(int j = 0; j < sizc; j++){
ans -= (a[2][j].x - (j == 0 ? 0 : a[2][j - 1].x)) * corss(i == 0 ? 0 : a[0][i - 1].x, a[0][i].x, 0, a[2][j].y) * (llt)a[0][i].y;
}
}
for(int i = 0; i < siza; i++){
for(int j = 0; j < sizb; j++){
for(int k = 0; k < sizc; k++){
llt l1, l2, l3;
l1 = corss(j == 0 ? 0 : a[1][j - 1].x, a[1][j].x, k == 0 ? 0 : a[2][k - 1].x, a[2][k].x);
if(l1 == 0) continue;
l2 = corss(i == 0 ? 0 : a[0][i - 1].x, a[0][i].x, 0, a[2][k].y);
if(l2 == 0) continue;
l3 = min(a[0][i].y, a[1][j].y);
if(l3 == 0) continue;
ans += l1 * l2 * l3;
}
}
}
// t2 = clock();
// printf("%lg\n",(double)(t2-t1)/CLOCKS_PER_SEC);
print(ans);
printf("\n");
}
}
int main(){
GetData();
maybe_ok::main();
}
然后是数据
30000000 30000000 30000000 30000000 3035720518499643645 13029