关于内存访问
  • 板块学术版
  • 楼主钰瑾_恋涵
  • 当前回复4
  • 已保存回复4
  • 发布时间2023/3/12 19:48
  • 上次更新2023/10/23 21:43:54
查看原帖
关于内存访问
399716
钰瑾_恋涵楼主2023/3/12 19:48

在今天月赛 Div2 T2 考场上我写了如下代码:

int n, a[N];
uint f[N][N], g[N][N], ans;
int main() {
    n = read(); For(i, 1, n) a[i] = read();
    sort(a + 1, a + n + 1), reverse(a + 1, a + n + 1);
    For(i, 1, n) For(j, i, n) f[i][j] = f[i][j - 1] + a[i] / a[j];
    For(j, 1, n) {
        for (int l = j + 1, r = 0; l <= n; l = r + 1) {
            r = l; int val = a[j] / a[l];
            while (r < n && a[j] / a[r + 1] == val) ++r;
            For(i, 1, j - 1) g[i][j] += (f[i][r] - f[i][l - 1]) * val;
        }
    }
    For(i, 1, n) For(j, i + 1, n) 
        ans += a[i] / a[j] * g[i][j];
    put(ans);
	return 0;
}

本机 1~n 的数据跑了 9s 左右,洛谷 2.5s 跑过。

为了使数组访问连续,我将其 f,g 两个数组两位交换,改成这样:

int n, a[N], cnt;
uint f[N][N], g[N][N], ans;
int main() {
    n = read(); For(i, 1, n) a[i] = read();
    sort(a + 1, a + n + 1), reverse(a + 1, a + n + 1);
    For(i, 1, n) For(j, i, n) f[j][i] = f[j - 1][i] + a[i] / a[j];
    For(j, 1, n) {
        for (int l = j + 1, r = 0; l <= n; l = r + 1) {
            r = l; int val = a[j] / a[l];
            while (r < n && a[j] - val * a[r + 1] < a[r + 1]) ++r;
            For(i, 1, j - 1) g[j][i] += (f[r][i] - f[l - 1][i]) * val, ++cnt;
        }
    }
    For(j, 1, n) For(i, 1, j - 1)
        ans += a[i] / a[j] * g[j][i];
    put(ans);
	return 0;
}

本机只跑了 0.6s,洛谷 0.7s。

经测试,1~n 的数据有 1e9 的枚举量,不能理解。。。

2023/3/12 19:48
加载中...