ABC269F 题解

注意到第 \(i\) 行和第 \(i+2\) 行被删除的格子的排列顺序相同,格子上的数差了 \(2m\)

于是处理出第 \(i,i+1\) 行的答案 \(a_i,a_{i+1}\),有值的格子的个数 \(c_i,c_{i+1}\)

\(s(i)=\dfrac{(i-1)i}2\),也就是 \(\sum_{j=1}^{i-1}j\)

\(i,i+2,i+4\cdots\) 行的和:\(a_i \times cnt_i + 2m \times c_i \times s(cnt_i)\)

\(i+1,i+3\cdots\) 行的和:\(a_{i+1}\times cnt_{i+1} + 2m \times c_{i+1} \times s(cnt_{i+1})\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int p = 998244353;

int n, m;

ll s1(ll x) {return x * (x - 1) / 2 % p;}

pair<ll, ll> calc(ll x, ll l, ll r)
{
    if((x + l) & 1) l ++;
    if((x + r) & 1) r --;

    ll fs = (x - 1) * m % p;
    ll len = (r - l + 2) / 2;
    
    return {((fs + l + fs + r) * len / 2) % p, len};
}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n >> m;

    int q; cin >> q;
    while(q --)
    {
        int x, y, u, v; 
        cin >> x >> u >> y >> v;
        
        auto t1 = calc(x, y, v);
        auto t2 = calc(x + 1, y, v);

        int l1 = (u - x + 2) / 2, l2 = u - x + 1 - l1;
        
        ll ans = 0;
        ans += t1.first * l1 + m * 2 * t1.second % p * s1(l1);
        ans += t2.first * l2 + m * 2 * t2.second % p * s1(l2);
        
        cout << ans % p << "\n";
    }

    return 0;
}

或者考虑容斥,令 \(f(x,y)=\sum_{i=1}^x\sum_{j=1}^y((i-1)m+j)[(i+j)\bmod 2=0]\)

\(S(i)=\dfrac{(i+1)i}2\),也就是等差数列和。

\(S'(i)\) 为去掉偶数项的 \(S(i)\) 的和。

考虑化简式子:

\[\begin{aligned} f(x,y)&=\sum_{i=1}^x\sum_{j=1}^y((i-1)m+j)[(i+j)\bmod 2=0] \\ &=\sum_{i=1}^x\sum_{j=1}^y(i-1)m[(i+j)\bmod 2=0]+ \sum_{i=1}^x\sum_{j=1}^yj[(i+j)\bmod 2=0] \\ &=m\lfloor\frac {y}2\rfloor S'(x-1)+ m\lfloor\frac{y+1}2\rfloor (S(x-1)-S'(x-1))+ \lfloor\frac {x}2\rfloor (S(y)-S'(y))+ \lfloor\frac {x+1}2\rfloor S'(y) \\ \end{aligned} \]

于是答案就是

\(f(B, D)- f(A - 1, D)- f(B, C - 1)+ f(A - 1, C - 1)\)


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int p = 998244353;

ll s1(ll x) {return x * (x + 1) / 2 % p;}
ll s2(ll x) {return (x + (x & 1)) * ((x + 1) / 2) / 2 % p;}

int n, m, q;

ll s(ll x, ll y)
{
    ll ans = 0;
    ans += (x / 2) % p * (s1(y) - s2(y)) + ((x + 1) / 2) % p * s2(y);
    ans += m * (y / 2) % p * s2(x - 1) + m * ((y + 1) / 2) % p * (s1(x - 1) - s2(x - 1));
    return ans % p;
}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n >> m >> q;
    while(q --)
    {
        int lx, rx, ly, ry;
        cin >> lx >> rx >> ly >> ry;
        ll ans = 0;
        ans += s(rx, ry);
        ans -= s(lx - 1, ry);
        ans -= s(rx, ly - 1);
        ans += s(lx - 1, ly - 1);
        cout << (ans % p + p) % p << "\n";
    }

    return 0;
}
posted @ 2024-08-03 11:09  adam01  阅读(29)  评论(0)    收藏  举报