QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#71817#2998. 皮配He_Ren0 0ms0kbC++235.7kb2023-01-12 01:22:422023-01-12 01:23:49

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-01-12 01:23:49]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:0kb
  • [2023-01-12 01:22:42]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAXN = 1e3 + 5;
const int MAXM = 2.5e3 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;

inline void add_mod(int &a, int b) {
    a += b;

    if (a >= mod)
        a -= mod;
}

struct Bagdp {
    int dp[MAXM], C0, C1, sum;
    void init(int _C0, int _C1) {
        C0 = _C0;
        C1 = _C1;
        memset(dp, 0, (C0 + 1) << 2);
        dp[0] = 1;
        sum = 0;
    }
    void insert(int x) {
        int mni = max(0, sum - C1);
        int mxi = min(sum, C0 - x);

        for (int i = mxi; i >= mni; --i)
            add_mod(dp[i + x], dp[i]);

        sum += x;

        for (int i = mni; i < sum - C1; ++i)
            dp[i] = 0;
    }
};

int c[MAXN], a[MAXN], fob[MAXN];

void solve(void) {
    int n, d;
    int C0, C1, D0, D1;
    scanf("%d%*d%d%d%d%d", &n, &C0, &C1, &D0, &D1);

    for (int i = 1; i <= n; ++i)
        scanf("%d%d", &c[i], &a[i]);

    memset(fob, -1, (n + 1) << 2);
    scanf("%d", &d);

    for (int i = 1; i <= d; ++i) {
        int x, y;
        scanf("%d%d", &x, &y);
        fob[x] = y;
    }

    static vector<int> pt[MAXN];
    static int suma[MAXN];
    static bool spec[MAXN];
    fill(pt + 1, pt + n + 1, vector<int>());
    memset(suma, 0, (n + 1) << 2);
    memset(spec, 0, n + 1);

    for (int i = 1; i <= n; ++i) {
        pt[c[i]].push_back(i);
        suma[c[i]] += a[i];
        spec[c[i]] |= fob[i] != -1;
    }

    for (int i = 1; i <= n; ++i)
        if (suma[i] > max(C0, C1)) {
            printf("0\n");
            return;
        }

    if (accumulate(suma + 1, suma + n + 1, 0) > min(C0 + C1, D0 + D1)) {
        printf("0\n");
        return;
    }

    static Bagdp bagC, bagD;
    bagC.init(C0, C1);
    bagD.init(D0, D1);

    for (int k = 1; k <= n; ++k)
        if (suma[k] && !spec[k]) {
            bagC.insert(suma[k]);

            for (int u : pt[k])
                bagD.insert(a[u]);
        }

    static int dp[MAXM][MAXM];

    for (int i = 0; i <= C0; ++i)
        for (int j = 0; j <= D0; ++j)
            dp[i][j] = 0;

    dp[0][0] = 1;

    int sum = 0;

    for (int k = 1; k <= n; ++k)
        if (suma[k] && spec[k]) {
            vector<pii> prob[2];

            for (int t = 0; t <= 1; ++t) {
                if (suma[k] > (t == 0 ? C0 : C1))
                    continue;

                static Bagdp curbag;
                curbag.init(D0, D1);
                int must[2] = {0, 0};

                for (int u : pt[k]) {
                    if (fob[u] != -1 && ((fob[u] >> 1) & 1) == t)
                        must[!(fob[u] & 1)] += a[u];
                    else
                        curbag.insert(a[u]);
                }

                for (int i = 0; i <= D0 && i <= curbag.sum; ++i)
                    if (i + must[0] <= D0 && curbag.sum - i + must[1] <= D1) {
                        if (!curbag.dp[i])
                            continue;

                        prob[t].emplace_back(i + must[0], curbag.dp[i]);
                    }
            }

            int mnC = max(0, sum - C1);
            int mnD = max(0, sum - D1);

            for (int i = min(sum, C0); i >= mnC; --i)
                for (int j = min(sum, D0); j >= mnD; --j)
                    if (dp[i][j]) {
                        ll cur = dp[i][j];

                        if (i + suma[k] <= C0) {
                            int *nxtdp = dp[i + suma[k]];

                            for (pii it : prob[0])
                                if (j + it.second <= D0)
                                    add_mod(nxtdp[j + it.first], cur * it.second % mod);
                        }

                        {
                            int *nxtdp = dp[i];

                            for (pii it : prob[1])
                                if (it.first > 0 && j + it.second <= D0)
                                    add_mod(nxtdp[j + it.first], cur * it.second % mod);

                            if (prob[1].size() && prob[1][0].second == 0)
                                nxtdp[j] = (ll)dp[i][j] * prob[1][0].first % mod;
                            else
                                nxtdp[j] = 0;
                        }
                    }

            sum += suma[k];
        }

    static int sumC[MAXM], sumD[MAXM];
    memcpy(sumC, bagC.dp, (C0 + 1) << 2);
    memcpy(sumD, bagD.dp, (D0 + 1) << 2);

    for (int i = 1; i <= C0; ++i)
        add_mod(sumC[i], sumC[i - 1]);

    for (int i = 1; i <= D0; ++i)
        add_mod(sumD[i], sumD[i - 1]);

    auto getC = [&](int l, int r) {
        l = max(l, 0);
        r = min(r, C0);

        if (l > r)
            return 0;

        return l == 0 ? sumC[r] : (sumC[r] - sumC[l - 1] + mod) % mod;
    };
    auto getD = [&](int l, int r) {
        l = max(l, 0);
        r = min(r, D0);

        if (l > r)
            return 0;

        return l == 0 ? sumD[r] : (sumD[r] - sumD[l - 1] + mod) % mod;
    };

    int ans = 0;

    for (int i = 0; i <= C0; ++i)
        if (sum - i <= C1)
            for (int j = 0; j <= D0; ++j)
                if (sum - j <= D1) {
                    if (!dp[i][j])
                        continue;

                    int LC = sum + bagC.sum - C1 - i, RC = C0 - i;
                    int LD = sum + bagD.sum - D1 - j, RD = D0 - j;

                    add_mod(ans, (ll)dp[i][j] * getC(LC, RC) % mod * getD(LD, RD) % mod);
                }

    printf("%d\n", ans);
}

int main(void) {
    freopen("10.in", "r", stdin);

    int T;
    scanf("%d", &T);

    while (T--)
        solve();

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

input:

5
1 1
1 1 1 1
1 1
1
1 0
1 1
1 1 1 1
1 1
0
1 1
1 1 1 1
1 1
1
1 1
1 1
1 1 1 1
1 1
1
1 2
1 1
1 1 1 1
1 1
1
1 3

output:


result:


Test #2:

score: 0
Time Limit Exceeded

input:

5
10 10
100 100 100 100
2 9
7 10
3 10
3 10
6 10
4 10
2 10
6 10
1 10
10 10
10
7 0
8 3
5 1
4 2
6 1
3 0
1 2
10 0
2 1
9 2
10 10
100 100 100 99
6 10
7 10
5 10
5 10
10 10
5 10
2 9
3 6
7 10
3 10
5
10 2
6 3
4 2
7 0
3 1
10 10
96 100 100 8
3 10
9 10
2 10
3 10
3 10
2 10
3 8
9 5
2 10
3 10
5
9 3
10 1
8 0
1 1
6 2...

output:


result:


Test #3:

score: 0
Dangerous Syscalls

input:

5
20 20
93 93 100 97
6 3
19 7
6 10
2 7
5 6
11 7
4 10
17 10
1 7
19 4
14 5
20 7
15 3
6 7
5 6
15 10
3 7
5 10
15 6
1 7
0
20 20
100 100 100 100
20 10
7 9
2 8
5 10
4 6
1 10
4 10
17 10
1 6
5 10
12 10
9 6
12 8
1 10
10 10
13 10
12 10
10 10
13 7
18 10
0
20 20
98 96 100 10
3 5
8 5
19 7
3 6
19 5
3 6
5 4
6 5
6 3...

output:


result:


Test #4:

score: 0
Dangerous Syscalls

input:

5
30 30
100 98 94 97
12 2
27 5
25 5
24 4
14 5
4 6
22 7
2 3
30 8
1 2
7 5
2 2
20 5
11 7
15 5
18 3
11 3
1 4
25 5
11 2
15 4
12 5
3 8
12 7
6 3
30 8
19 5
13 3
21 9
4 3
0
30 30
93 99 92 93
24 3
23 10
17 5
22 5
17 7
29 10
18 6
7 5
17 6
9 7
3 6
16 6
9 5
10 4
6 5
20 6
2 7
20 5
3 3
9 3
2 5
29 6
9 8
1 4
12 5
1 ...

output:


result:


Test #5:

score: 0
Dangerous Syscalls

input:

5
30 30
482 500 500 500
17 10
15 10
25 10
14 8
9 10
1 10
15 10
23 10
13 8
15 9
15 8
20 10
19 10
6 10
18 8
23 10
3 10
28 10
13 10
2 10
15 10
17 10
1 10
2 10
14 10
11 10
29 7
24 10
14 10
30 10
13
15 3
25 3
18 2
23 2
1 3
7 0
4 2
20 0
26 2
9 1
3 2
30 2
24 1
30 30
485 500 500 489
22 10
7 10
10 10
1 8
9 1...

output:


result:


Test #6:

score: 0
Dangerous Syscalls

input:

5
500 500
998 974 1000 975
427 4
84 3
313 2
161 4
371 2
481 4
5 3
80 2
156 6
448 4
424 2
302 1
277 1
14 2
343 6
431 2
452 3
369 3
427 2
245 6
413 3
317 3
1 3
447 1
337 4
181 2
224 5
243 3
494 2
248 3
152 5
430 4
119 4
290 2
19 3
93 2
274 4
14 2
67 2
56 2
75 5
454 3
407 1
324 3
138 5
283 4
274 4
472 ...

output:


result:


Test #7:

score: 0
Time Limit Exceeded

input:

5
500 30
1000 982 976 986
1 2
23 3
22 1
5 6
22 4
27 2
22 5
18 6
19 1
11 4
30 2
20 4
2 3
18 2
2 3
18 4
8 2
27 4
3 3
27 4
19 5
2 1
28 4
18 2
10 1
11 4
29 3
20 2
22 3
4 2
4 4
26 3
3 3
3 4
3 5
18 3
3 1
4 3
11 3
15 6
19 2
21 3
23 4
12 2
14 4
2 1
30 2
15 4
10 3
21 3
12 6
11 3
14 2
5 2
30 1
11 2
25 4
13 2
...

output:


result:


Test #8:

score: 0
Time Limit Exceeded

input:

5
500 500
975 1000 1000 1000
322 4
4 1
327 6
287 3
352 3
493 3
8 4
89 1
348 3
277 2
158 2
375 2
457 3
155 2
94 2
423 2
407 4
405 2
474 4
44 2
103 3
430 4
61 2
83 2
314 2
143 5
468 2
481 3
241 2
388 4
453 3
301 3
225 4
375 2
181 5
259 5
220 4
126 3
301 4
150 1
383 1
394 3
177 1
329 4
448 1
394 3
129 ...

output:


result:


Test #9:

score: 0
Time Limit Exceeded

input:

5
1000 1000
2500 2500 2500 2500
285 3
51 3
740 5
140 4
758 4
740 2
493 7
155 3
30 6
380 2
235 3
447 5
500 4
402 2
358 2
936 4
48 4
793 4
994 1
668 5
607 3
694 4
426 4
377 7
314 7
83 7
948 3
423 6
229 4
920 3
498 5
262 3
22 4
25 3
661 4
420 2
689 5
509 5
401 3
213 4
286 4
699 3
466 4
430 3
734 4
420 ...

output:


result:


Test #10:

score: 0
Time Limit Exceeded

input:

5
1000 1000
2500 2500 2500 2500
801 5
102 2
581 5
589 5
493 6
214 2
604 10
391 3
7 2
555 4
594 3
614 8
230 5
900 4
605 5
869 6
991 4
820 2
124 4
630 2
694 3
244 6
170 4
8 2
360 1
394 3
512 7
823 3
89 3
988 5
433 4
858 6
362 4
995 4
181 3
718 3
275 2
325 4
11 4
5 2
222 4
209 5
562 1
158 2
908 3
496 3...

output:


result: