Link
首先有一个比较显然的(O(nm))的dp。
同时我们可以发现,对于一个洞,它只能影响到离他Manhattan距离不大于(2)的位置。
剩下的点就只能够从它左下方的点转移过来。
按对角线顺序dp,用map维护被洞影响到的点特殊转移即可。
#include<cctype>
#include<cstdio>
#include<vector>
#include<utility>
#include<algorithm>
#include<unordered_map>
using i64=long long;
using pi=std::pair<int,int>;
const int P=998244353;
char ibuf[1<<22],*iS=ibuf;
int ans;std::vector<pi>vec;std::unordered_map<i64,int>val;std::unordered_map<int,int>f,g;
int read(){int x=0,f=1;while(isspace(*iS))++iS;if(*iS=='-')f=-1,++iS;while(isdigit(*iS))(x*=10)+=*iS++&15;return f*x;}
int dp(int x,int y){return f.count(x-y)? f[x-y]:0;}
i64 hash(int x,int y){return x*10000000000ll+y;}
void solve(int o)
{
f.clear(),g.clear();
for(auto[x,y]:vec)
{
if(f.count(x-y)&&((x+y)&1)==o) ans=(ans+1ll*f[x-y]*(g[x-y]-x))%P;
if(val.count(hash(x,y))) f[x-y]=val[hash(x,y)];
else if(((x+y)&1)==o) f[x-y]=std::min(dp(x+1,y),dp(x,y+1));
else f[x-y]=std::max(dp(x+1,y),dp(x,y+1));
g[x-y]=x;
}
for(auto it:f)
{
int x=g[it.first],y=x-it.first;
if(((x+y)&1)==o) ans=(ans+1ll*it.second*std::min(x,y))%P;
}
}
int main()
{
fread(ibuf,1,1<<22,stdin);
read(),read();int k=read();
while(k--)
{
int x=read(),y=read();val[hash(x,y)]=read();
for(int i=0;i<=2;++i) for(int j=0;i+j<=2;++j) if(x>i&&y>j) vec.emplace_back(x-i,y-j);
}
std::sort(vec.begin(),vec.end()),vec.erase(std::unique(vec.begin(),vec.end()),vec.end()),std::reverse(vec.begin(),vec.end());
solve(0),solve(1),printf("%d",(ans+P)%P);
}