求助卡常
  • 板块学术版
  • 楼主NightTide
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/10/17 15:31
  • 上次更新2023/10/27 07:08:41
查看原帖
求助卡常
547908
NightTide楼主2022/10/17 15:31

实测是代码中分割线之前的超时,基数排序跑了 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
2022/10/17 15:31
加载中...