如果你有一道题一上午都没调出来
那么一定是你取模取错了QAQ
下意识地对(1e9)+7取了模,现在才发现是(1e9)+9
这个首先推一下公式,然后开三个树状数组维护一下就好了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int N=1200000+5;
typedef long long ll;
const int p=(1e9)+9;
int mp[N],c[N],down[N];
int n,m;
int id(int x,int y){
return (x-1)*m+y;
}
struct BIT{
ll d[N];
int vis[N],T;
void clear(){T++;}
int lowbit(int x){return x&-x;}
void add(int x,ll v){
for(;x<=m;x+=lowbit(x)){
if(vis[x]!=T)vis[x]=T,d[x]=0;
d[x]=(d[x]+v)%p;
}
}
ll sum(int x){
ll ans=0;
for(;x;x-=lowbit(x))if(vis[x]==T)ans=(ans+d[x])%p;
return ans;
}
}t1,t2,t3;
int main(){
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
scanf("%d%d",&n,&m);
int k;scanf("%d",&k);
for(int i=1;i<=k;i++){
int x,y;scanf("%d%d",&x,&y);
mp[id(x,y)]=1;
}
for(int i=1;i<=n;i++){
int mark=0;
for(int j=1;j<=m;j++){
int t=id(i,j);
if(mp[t])mark=j;
else c[t]=j-mark-1;
}
mark=m+1;
for(int j=m;j>=1;j--){
int t=id(i,j);
if(mp[t])mark=j;
else c[t]=min(c[t],mark-j-1);
}
}
for(int j=1;j<=m;j++){
int mark=n+1;
for(int i=n;i>=1;i--){
int t=id(i,j);
if(mp[t])mark=i;
else down[t]=mark-i-1;
}
}
ll ans=0;
for(int j=1;j<=m;j++){
t1.clear();t2.clear();t3.clear();
int top=0;
for(int i=1;i<=n;i++){
int t=id(i,j);
if(mp[t]){top=i;t1.clear();t2.clear();t3.clear();continue;}
ans+=t1.sum(c[t])*down[t]%p;
ans+=t2.sum(c[t])*c[t]*down[t]%p;
ans+=(t3.sum(m)-t3.sum(c[t]))*(c[t]-1)*c[t]/2*down[t]%p;
ans%=p;t=id(i-1,j);
if (i==1) continue;
if (c[t]){
t1.add(c[t],-1ll*c[t]*(c[t]+1)/2*(i-1-top-1));
t2.add(c[t],c[t]*(i-1-top-1));
t3.add(c[t],i-1-top-1);
}
}
}
printf("%lld\n",ans);
return 0;
}