QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#421657#6533. Traveling in CellswhizhouTL 194ms4040kbC++144.2kb2024-05-25 23:54:162024-05-25 23:54:18

Judging History

你现在查看的是最新测评结果

  • [2024-05-25 23:54:18]
  • 评测
  • 测评结果:TL
  • 用时:194ms
  • 内存:4040kb
  • [2024-05-25 23:54:16]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define fo(i, x, y) for(int i = x, endI = y; i <= endI; ++ i)

#define N 300000

void read(int &);

typedef long long ll;

// 二分求位置线段树数组及动态开点变量 queryTree
int sz[N << 6], ls[N << 6], rs[N << 6], fa[N << 6], rt[N + 1];

int totTreePoints;

// 计算区间和线段树数组 sumTree
ll sv[N << 6];

// 用于记录询问信息
int a[25][N + 1];

// 输入
int c[N + 1], val[N + 1];

int n, m;

void buildSumTree(int t, int l, int r) {
    if (l == r) {
        sv[t] = val[l];
        return;
    }
    int mid = l + r >> 1;
    buildSumTree(t << 1, l, mid),
    buildSumTree(t << 1 | 1, mid + 1, r);
    sv[t] = sv[t << 1] + sv[t << 1 | 1];
}

void addQueryTree(int &t, int l, int r, int k, int f, int adder) {
    if (! t) {
        t = ++ totTreePoints;
        ls[t] = rs[t] = sz[t] = 0;
        fa[t] = f;
    }
    sz[t] += adder;
    if (l == r)
        return;
    int mid = l + r >> 1;
    k <= mid ? addQueryTree(ls[t], l, mid, k, t, adder) : addQueryTree(rs[t], mid + 1, r, k, t, adder);
}

void addSumTree(int t, int l, int r, int k, int adder) {
    sv[t] += adder;
    if (l == r)
        return;
    int mid = l + r >> 1;
    k <= mid ? addSumTree(t << 1, l, mid, k, adder) : addSumTree(t << 1 | 1, mid + 1, r, k, adder);
}

int queryLeft(int t, int l, int r, int k, int d) {
    if (l == r) {
        fo(i, 1, t) if (sz[a[d][i]])
            return l;
        return 0;
    }
    int mid = l + r >> 1;
    int point = 0;
    if (k > mid) {
        fo(i, 1, t) a[d + 1][i] = rs[a[d][i]];
        point = queryLeft(t, mid + 1, r, k, d + 1);
        if (point == mid + 1) {
            fo(i, 1, t) a[d + 1][i] = ls[a[d][i]];
            int point1 = queryLeft(t, l, mid, k, d + 1);
            if (point1)
                point = point1;
        }
    } else {
        fo(i, 1, t) a[d + 1][i] = ls[a[d][i]];
        point = queryLeft(t, l, mid, k, d + 1);
    }
    return point;
}

int queryRight(int t, int l, int r, int k, int d) {
    if (l == r) {
        fo(i, 1, t) if (sz[a[d][i]])
            return l;
        return 0;
    }
    int mid = l + r >> 1;
    int point = 0;
    if (k <= mid) {
        fo(i, 1, t) a[d + 1][i] = ls[a[d][i]];
        point = queryRight(t, l, mid, k, d + 1);
        if (point == mid) {
            fo(i, 1, t) a[d + 1][i] = rs[a[d][i]];
            int point1 = queryRight(t, mid + 1, r, k, d + 1);
            point =  point1 ? point1 : point;
        }
    } else {
        fo(i, 1, t) a[d + 1][i] = rs[a[d][i]];
        point = queryRight(t, mid + 1, r, k, d + 1);
    }
    return point;
}

ll calcSum(int t, int l, int r, int x, int y) {
    if (x <= l && r <= y)
        return sv[t];
    int mid = l + r >> 1;
    ll sumVal = 0;
    if (x <= mid)
        sumVal = calcSum(t << 1, l, mid, x, y);
    if (y > mid)
        sumVal += calcSum(t << 1 | 1, mid + 1, r, x, y);
    return sumVal;
}

int main() {
    int T; read(T);
    while (T--) {
        read(n), read(m);
        fo(i, 1, n) read(c[i]);
        fo(i, 1, n) read(val[i]);

        // 多组数据初始化
        // 清零
        totTreePoints = 0;
        fo(i, 1, n) rt[i] = 0;
        // 初始化
        buildSumTree(1, 1, n);
        fo(i, 1, n)
            addQueryTree(rt[c[i]], 1, n, i, 0, 1);

        fo(i, 1, m) {
            int opt, p, x;
            read(opt), read(p), read(x);
            if (opt == 1) {
                addQueryTree(rt[c[p]], 1, n, p, 0, -1);
                c[p] = x;
                addQueryTree(rt[x], 1, n, p, 0, 1);
            } else if (opt == 2) {
                addSumTree(1, 1, n, p, x - val[p]);
                val[p] = x;
            } else {
                fo(i, 1, x) read(a[0][i]), a[1][i] = rt[a[0][i]];
                int leftPoint = queryLeft(x, 1, n, p, 1);
                int rightPoint = queryRight(x, 1, n, p, 1);
                printf("%lld\n", calcSum(1, 1, n, leftPoint, rightPoint));
            }
        }
    }

    return 0;
}

void read(int &x) {
    char ch = getchar(); x = 0;
    while (ch < '0' || ch > '9') ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + ch - 48, ch = getchar();
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3964kb

input:

2
5 10
1 2 3 1 2
1 10 100 1000 10000
3 3 1 3
3 3 2 2 3
2 5 20000
2 3 200
3 3 2 1 3
3 3 3 1 2 3
1 3 4
2 1 100000
1 2 2
3 1 2 1 2
4 1
1 2 3 4
1000000 1000000 1000000 1000000
3 4 4 1 2 3 4

output:

100
110
1200
21211
100010
4000000

result:

ok 6 numbers

Test #2:

score: 0
Accepted
time: 103ms
memory: 3916kb

input:

20000
15 15
1 1 3 3 2 3 3 3 3 3 2 3 2 3 3
634593973 158136379 707704004 998369647 831633445 263092797 937841412 451774682 552617416 483763379 50360475 794662797 74247465 537217773 901809831
3 6 4 1 3 5 10
3 5 7 1 2 3 4 5 9 10
3 4 3 3 8 9
2 13 608033129
3 15 2 3 5
1 9 3
3 8 4 1 3 7 10
2 6 727472865
3...

output:

2689089686
8377825475
1706073651
1439027604
2689089686
792730352
8904867081
8904867081
8270273108
831633445
692051585
2782432626
697783016
883944422
184057757
287523250
184057757
696388752
184057757
1675459344
2667693025
2614711258
4006992373
1767091974
5348541057
5348541057
390631780
2290216252
942...

result:

ok 200062 numbers

Test #3:

score: 0
Accepted
time: 194ms
memory: 4040kb

input:

2000
150 150
8 3 8 8 8 6 8 4 2 7 6 8 8 5 8 7 7 8 5 6 8 8 6 8 8 8 8 7 8 6 6 8 8 8 6 2 3 4 8 8 7 8 5 8 2 6 8 7 8 8 6 8 6 8 3 8 8 8 8 4 7 8 7 3 7 6 7 5 5 8 6 8 8 6 3 8 6 7 6 8 8 7 4 8 6 7 8 7 7 7 7 8 8 8 8 2 5 2 8 8 6 7 6 3 8 8 7 8 8 8 6 6 8 6 6 7 5 8 8 8 7 8 7 7 6 8 8 8 8 8 8 6 5 7 5 5 8 7 8 7 7 7 6 5...

output:

4449391171
3290849667
852793841
5178673994
995994209
11431868919
4327723427
5071541023
3032743466
962345334
2997656427
4534278452
3851900075
3611231417
5071541023
1477584218
1299005818
1299005818
2145605244
854143763
886347565
2081234124
2333808475
2455955801
4179722063
2328504333
1473735464
4107685...

result:

ok 199987 numbers

Test #4:

score: -100
Time Limit Exceeded

input:

10
30000 30000
3 4 2 4 4 4 4 3 4 3 4 3 4 3 4 4 2 4 4 4 4 4 3 3 3 4 3 4 3 4 3 3 4 2 4 3 3 3 3 4 3 4 4 4 4 2 3 3 4 2 3 4 4 4 4 1 4 4 4 4 4 4 4 4 3 3 3 4 4 4 4 4 2 3 4 4 4 4 3 4 4 3 3 3 4 4 3 4 4 2 3 4 4 4 4 3 2 4 3 4 3 2 4 4 3 4 2 2 4 4 4 4 2 4 3 2 4 4 3 4 4 4 2 4 4 3 2 3 2 3 3 3 4 2 4 3 4 1 4 3 4 4 4...

output:

6959437173
934970676
72461245502
8365928740
8384151048
984567228
12482909122
1904927816
15134139942
3759040688
92670874909
332468911
5936663371
3562978848
1300592004
10314009201
5581540905
131246926443
15087184135864
4077066271
1124704817
1520626740
4388174158
744377942
2770411457
6231852240
1508724...

result: