[ABC269F] Numbered Checker 题解

[ABC269F] Numbered Checker Solution

更好的阅读体验戳此进入

题面

存在 $ n \times m $ 的网格图,在里面按照从左至右,从上至下的顺序填写 $ [1, n \times m] $ 所有数,然后使所有行数与列数之和为奇数的格子中的数推平为 $ 0 \(。\) q $ 次询问求子矩形权值和。

Solution

尝试简单推一下式子,显然对于奇数行,为 $ 1 + km, 3 + km, 5 + km, \cdots $,偶数行同理。对于多行相加,奇数行则 $ k = 0, 2, 4, \cdots $,偶数行同理。也就是说我们讨论奇偶之后,对一行里做一下等差数列求和然后乘上奇数行行数,对 $ k $ 做一遍等差数列求和然后乘上奇数列列数和 $ m $ 即可。

同时注意对于偶数的求和需要全部转为偶数,反之全部转为奇数。

同时也可以用简单的容斥思想,每次计算左上角为 $ 1 $ 的四个矩形的值并处理,但实现难度与此方法接近。

同时整个过程中仅需 long long 即可,等差数列求和的除以 $ 2 $ 不需要用逆元,适当取模后也不需要用 __int128_t

Code

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>

#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW void* Edge::operator new(size_t){static Edge* P = ed; return P++;}

using namespace std;

mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}

typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;

#define MOD (998244353ll)

template < typename T = int >
inline T read(void);

int N, M;

ll QueryOdd(ll l, ll r){
    if(!(l & 1))++l;
    if(!(r & 1))--r;
    if(l > r)return 0;
    return (((l + r) * (((r - l) >> 1) + 1)) >> 1) % MOD;
}
ll QueryEven(ll l, ll r){
    if(l & 1)++l;
    if(r & 1)--r;
    if(l > r)return 0;
    return (((l + r) * (((r - l) >> 1) + 1)) >> 1) % MOD;
}
ll CntOdd(ll l, ll r){
    if(!(l & 1))++l;
    if(!(r & 1))--r;
    if(l > r)return 0;
    return (((r - l) >> 1) + 1) % MOD;
}
ll CntEven(ll l, ll r){
    if(l & 1)++l;
    if(r & 1)--r;
    if(l > r)return 0;
    return (((r - l) >> 1) + 1) % MOD;
}

int main(){
    N = read(), M = read();
    int Q = read();
    while(Q--){
        ll ans(0);
        int a = read(), b = read(), c = read(), d = read();
        (ans += QueryOdd(c, d) * CntOdd(a, b) % MOD) %= MOD;
        (ans += ((QueryOdd(a, b) - CntOdd(a, b) + MOD) % MOD) * CntOdd(c, d) % MOD * M % MOD) %= MOD;
        (ans += QueryEven(c, d) * CntEven(a, b) % MOD) %= MOD;
        (ans += ((QueryEven(a, b) - CntEven(a, b) + MOD) % MOD) * CntEven(c, d) % MOD * M % MOD) %= MOD;
        printf("%lld\n", ans);
    }
    fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}

template < typename T >
inline T read(void){
    T ret(0);
    int flag(1);
    char c = getchar();
    while(c != '-' && !isdigit(c))c = getchar();
    if(c == '-')flag = -1, c = getchar();
    while(isdigit(c)){
        ret *= 10;
        ret += int(c - '0');
        c = getchar();
    }
    ret *= flag;
    return ret;
}

UPD

update-2023_01_25 初稿

posted @ 2023-02-15 19:05  Tsawke  阅读(26)  评论(0)    收藏  举报