QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#466481#8049. Equal Sumsucup-team2307#TL 1ms3692kbC++205.3kb2024-07-07 21:13:082024-07-07 21:13:08

Judging History

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

  • [2024-07-07 21:13:08]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:3692kb
  • [2024-07-07 21:13:08]
  • 提交

answer

#include <bits/stdc++.h>
#pragma GCC optimize ("Ofast, unroll-loops")

using namespace std;

using ll = long long;
//#define int ll

#define fi first
#define se second
#define pb push_back

const int mod = 998244353;

const int N = 501;
const int L = 500;
const int S = 2 * 500 * 500 + 1;
const int M = 500 * 500 + 5;

vector<int> dp[2*N];
int z[2*N];
int pref[S];

int sub(int a, int b)
{
    return (a >= b) ? a-b : mod+a-b;
}
int add(int a, int b)
{
    int s = a+b;
    return (s>=mod) ? s-mod : s;
}
void add(int idfrom, int idto, int lx, int rx, int cl, int cr)
{
    int n = dp[idfrom].size();
    int z0 = z[idfrom];

    cl = max<int>(cl, -z0+lx);
    cr = min<int>(cr, n-1-z0+rx);
    if (cl > cr)
    {
        z[idto] = 0;
        dp[idto] = {0};
        return;
    }

    int intl, intr;
//    intl = 0;
//    intr = n-1;
    intl = max(0, cl-rx+z0);
    intr = min(n-1, cr-lx+z0);

    pref[intl] = 0;
    for (int i=intl; i<=intr; i++)
        pref[i+1] = add(pref[i], dp[idfrom][i]);

    bool started = false;
    for (int i=cl; i<=cr; i++)
    {
        int x1 = min(i-lx+z0+1, n);
        int x2 = min(i-rx+z0, n);

        if (started)
            dp[idto][i-cl] = sub(pref[max<int>(x1, 0)], pref[max<int>(x2, 0)]);
        else
        {
            int x = sub(pref[max<int>(x1, 0)], pref[max<int>(x2, 0)]);
            if (x != 0)
            {
                started = true;
                z[idto]=-cl;
                dp[idto].assign(cr-cl+1, 0);
                dp[idto][i-cl] = x;
            }
            else
            {
                cl++;
            }
        }
    }
    if (!started)
    {
        z[idto] = 0;
        dp[idto] = {0};
        return;
    }
    else
    {
        while(dp[idto].back() == 0)
            dp[idto].pop_back();
    }
}

int n, m;
int ans[N][N];
vector<pair<int, int> > a;
vector<pair<int, int> > b;

vector<pair<int, int> > nt[505][505];
int hx[505][505];
int hy[505][505];
void dfs(int x, int y)
{
    hx[x][y] = 0;
    hy[x][y] = 0;
    for (auto [i, j] : nt[x][y])
    {
        dfs(i, j);
        hx[x][y] = max(hx[x][y], hx[i][j] + (j==y));
        hy[x][y] = max(hy[x][y], hy[i][j] + (i==x));
    }
}
void fillnt(int lx, int rx, int ly, int ry)
{
    if (lx == rx)
    {
        for (int j=ly; j<ry; j++)
            nt[lx][j].pb({lx, j+1});
        return;
    }
    if (ly == ry)
    {
        for (int i=lx; i<rx; i++)
            nt[i][ly].pb({i+1, ly});
        return;
    }
    if (rx-lx > ry-ly)
    {
        int m = (lx+rx-1)/2;
        fillnt(lx, m, ly, ry);
        fillnt(m+1, rx, ly, ry);
        nt[m][ly].pb({m+1, ly});
        return;
    }
    {
        int m = (ly+ry-1)/2;
        fillnt(lx, rx, ly, m);
        fillnt(lx, rx, m+1, ry);
        nt[lx][m].pb({lx, m+1});
        return;
    }
}

void rec(int x, int y, int id)
{
//    cout<<x<<" "<<y<<" :\n";
//    for (int i=0; i<dp[id].size(); i++)
//        cout<<i-z[id]<<" -> "<<dp[id][i]<<"\n";

    if (z[id] >= 0 && z[id] < dp[id].size())
        ans[x][y] = dp[id][z[id]];

    for (auto [i, j] : nt[x][y])
    {
        if (nt[i][j].empty())
        {
            int l, r;
            if (i == x+1) l = a[x].fi, r = a[x].se;
            else l = b[y].fi, r = b[y].se;
            int s = 0;
            swap(l, r);
            l=-l, r=-r;
            l+=z[id], r+=z[id];
            l=max<int>(l, 0);
            r=min<int>(r, int(dp[id].size())-1);
            for (int i=l; i<=r; i++)
                s = add(s, dp[id][i]);
            ans[i][j] = s;
            continue;
        }
//        cout<<x<<" "<<y<<" "<<hx[x][y]<<" "<<hy[x][y]<<"\n";
#define L 500
        if (i == x+1)
            add(id, id+1, a[x].fi, a[x].se, -hx[i][j]*L, hy[i][j]*L);
        else
            add(id, id+1, b[y].fi, b[y].se, -hx[i][j]*L, hy[i][j]*L);
#undef L
        rec(i, j, id+1);
    }
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    cin.exceptions(cin.failbit);

    cin>>n>>m;

    a.assign(n, {1, 500});
    b.assign(m, {1, 500});
    for (auto& [l, r] : a) cin>>l>>r;
    for (auto& [l, r] : b) cin>>l>>r;
    for (auto& [l, r] : b)
    {
        swap(l, r);
        l = -l;
        r = -r;
    }

    dp[0] = {1};
    z[0] = 0;
    add(0, 1, a[0].fi, a[0].se, -1e9, 1e9);
    add(1, 2, b[0].fi, b[0].se, -1e9, 1e9);
    fillnt(1, n, 1, m);
    dfs(1, 1);

//    int s = 0;
//    for (int i=1; i<=n; i++)
//        for (int j=1; j<=m; j++)
//            s += hx[i][j] + hy[i][j];
//    cerr<<s*1.0/n/m<<endl;
//    return 0;

    rec(1, 1, 2);

    for (int i=1; i<=n; i++, cout<<"\n")
        for (int j=1; j<=m; j++)
            cout<<ans[i][j]<<" ";
}

/*
7 13
42 68
1 35
25 70
59 79
63 65
6 46
28 82
62 92
43 96
28 37
5 92
3 54
83 93
17 22
19 96
27 48
39 72
13 70
68 100
36 95

7 0 0 0 0 0 0 0 0 0 0 0 0
689 0 0 0 0 0 0 0 0 0 0 0 0
2925 695696 886361 3756893 13819357 0 0 0 0 0 0 0 0
0 6639451 206590571 967087824 917216759 116592235 349701 0 0 0 0 0 0
0 0 9702215 51592689 86599878 77449189 811457653 604649316 239717374 0 0 0 0
0 0 18955584 34805870 714691346 767072778 911093368 569558785 118212838 450448591 961439475 0 0
0 0 10 244156379 793033878 461717319 313992783 552554555 501476300 620390810 460595655 776372008 210
*/

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3692kb

input:

2 3
1 2
2 3
1 4
2 2
1 3

output:

2 0 0 
3 4 4 

result:

ok 6 numbers

Test #2:

score: -100
Time Limit Exceeded

input:

500 500
19 458
1 480
7 485
50 461
12 476
15 461
48 466
40 453
46 467
9 458
27 478
26 472
46 459
29 490
6 500
17 487
48 484
28 472
28 459
25 480
4 491
29 481
36 460
2 491
44 499
22 473
20 458
4 483
27 471
2 496
11 461
43 450
2 478
37 466
15 459
42 482
7 451
19 455
2 453
47 475
48 450
1 474
46 471
9 4...

output:


result: