如果你有一道题一上午都没调出来
那么一定是你取模取错了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; }