ABC-269解题报告
D. Do use hexagon grid
\(n^2\) 枚举两个格点,判断是否能直接走,能则连边,最后用 dfs 计算连通块个数。
E. Last Rook
由于不需要考虑斜向的冲突,所以考虑行和列分开二分。以行为例:
如果有若干连续行的棋子数量小于行数,则答案一定在这些行中,以此作为二分的 check。
F. Numbered Checker
显然每一行剩下的数都是一个等差数列。
考虑奇偶行分开计算:对于奇数行,只有奇数列能产生贡献;对于偶数行,只有偶数列能产生贡献。以奇数行为例:
具体地,若输入的四界分别为 \(u,d,l,r\),则只考虑奇数行时,我们将四界缩紧为 \(u',d',l',r'\)(为方便接下来处理),此时能产生贡献的列数为 \(len_{row}=(r'-l')/2+1\),行数为 \(len_{column}=(d'-u')/2+1\)。
显然贡献的左上角的值为 \(s_1=(u'-1)\times m+l'\),右上角为 \(s_2=(u'-1)\times m+r'\),则第一行的和 \(sum_{u'}=(s_1+s_2)\times len_{row}\)。
第二个产生贡献的行(即 \(u'+2\) 行)的和为 \(sum_{u'+2}=sum_{u'}+len_{row}\times 2m\),第三行为 \(sum_{u'+4}=sum_{u'}+len_{row}\times 4m\) 以此类推。可以发现每一行都含有一个 \(sum_{u'}\) 的项,单独提出来,得到 \(sum_{u'}\times len_{column}\),而每一行新加的贡献为 \(len_{row}\times 0m+len_{row}\times 2m+len_{row}\times 4m\cdots\),这也可以很容易得用等差数列求得。
偶数行偶数列的情况同理,由于操作完全相同,可以封装成函数调用两遍。
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
int add(int a,int b) {return (a+b)%mod;}
int mul(int a,int b) {return a*b%mod;}
signed main() {
int inv2=(mod+1)/2;
int n,m,q;
cin>>n>>m>>q;
while(q--) {
int l,r,u,d,ans=0;
cin>>u>>d>>l>>r;
auto solve=[&](bool flag) {
int u1=u,d1=d,l1=l,r1=r;
if(u1%2==flag) u1++;
if(d1%2==flag) d1--;
if(l1%2==flag) l1++;
if(r1%2==flag) r1--;
int lenrow=(r1-l1)/2+1,lencol=(d1-u1)/2+1;
int res=mul(mul(add(add(mul(u1-1,m),l1),add(mul(u1-1,m),r1)),lenrow),inv2);
(ans+=mul(res,lencol))%=mod;
(ans+=mul(mul(mul(mul(2*(lencol-1),m),lencol),inv2),lenrow))%=mod;
};
solve(0),solve(1);
cout<<ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号