QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1180#745843#9748. 最大公因数的平方和jlgxyhhoppitreeSuccess!2024-11-14 15:54:322024-11-14 15:54:32

Details

Extra Test:

Runtime Error

input:

5000
399 2883 4953 1303 4174 1070 2918 2249 3121 1625 2711 1142 2882 4864 2773 590 3994 3270 191 2346 3769 481 2141 169 349 3114 4536 3471 2580 3809 4108 2921 4757 1799 1402 1473 995 648 2908 1206 1259 3107 4707 3366 2017 2881 1542 587 943 2061 4538 36 89 3878 3502 3066 4489 3137 2910 2827 3580 1405...

output:


result:


IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#745843#9748. 最大公因数的平方和hhoppitree#RE 3569ms37776kbC++172.2kb2024-11-14 11:56:412024-11-14 15:54:51

answer

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5, M = 2e6 + 5;

int a[N], b[N], p1[N], c[M], p2[N], d[M], cnt1[N], cnt2[N];
vector<int> D[N];
unsigned int f[N], res[N];

struct op {
    int l, r, id;
} p[N << 2];

int sz;

int cmp(op x, op y) {
    return ((x.l - 1) / sz + 1 != (y.l - 1) / sz + 1 ? x.l < y.l : (((x.l - 1) / sz + 1) & 1) ? x.r < y.r : x.r > y.r);
}

signed main() {
    int n; scanf("%d", &n);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    for (int i = 1; i <= n; ++i) scanf("%d", &b[i]);
    for (int i = 1; i <= n; ++i) {
        f[i] += i * i;
        for (int j = i + i; j <= n; j += i) f[j] -= f[i];
        for (int j = i; j <= n; j += i) D[j].push_back(i);
    }
    for (int i = 1; i <= n; ++i) {
        p1[i] = p1[i - 1];
        for (auto j : D[a[i]]) {
            c[++p1[i]] = j;
        }
    }
    for (int i = 1; i <= n; ++i) {
        p2[i] = p2[i - 1];
        for (auto j : D[b[i]]) {
            d[++p2[i]] = j;
        }
    }
    int q, z = 0; scanf("%d", &q);
    for (int i = 1; i <= q; ++i) {
        int l1, r1, l2, r2; scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
        l1 = p1[l1 - 1] + 1, r1 = p1[r1];
        l2 = p2[l2 - 1] + 1, r2 = p2[r2];
        p[++z] = {l1 - 1, l2 - 1, i};
        p[++z] = {l1 - 1, r2, -i};
        p[++z] = {r1, l2 - 1, -i};
        p[++z] = {r1, r2, i};
    }
    sz = z / sqrt(p1[n]);
    sort(p + 1, p + z + 1, cmp);
    int z1 = 0, z2 = 0;
    unsigned int now = 0;
    for (int i = 1; i <= z; ++i) {
        while (z1 < p[i].l) {
            ++z1;
            now += cnt2[c[z1]];
            cnt1[c[z1]] += f[c[z1]];
        }
        while (z2 < p[i].r) {
            ++z2;
            now += cnt1[d[z2]];
            cnt2[d[z2]] += f[d[z2]];
        }
        while (z1 > p[i].l) {
            now -= cnt2[c[z1]];
            cnt1[c[z1]] -= f[c[z1]];
            --z1;
        }
        while (z2 > p[i].r) {
            now -= cnt1[d[z2]];
            cnt2[d[z2]] -= f[d[z2]];
            --z2;
        }
        res[abs(p[i].id)] += (p[i].id / abs(p[i].id) * now);
    }
    for (int i = 1; i <= q; ++i) printf("%u\n", res[i]);
    return 0;
}