注意到第 \(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;
}
标签:ll,int,题解,sum,cin,ans,ABC269F,s1
From: https://www.cnblogs.com/adam01/p/18340203