P8915 题解
dAniel_lele · · 题解
是一血的题解捏(
思路
先考虑
总数
先考虑总数,共有
相邻
没有黑格子情况下,相邻的共有
答案
设相邻的有
k=3
前面相邻的还有有用的,我们还是考虑容斥计算,总数减去钦定两个相邻,再加上三个都相邻的。
总数
容易发现是
相邻
首先每个
然后对于每个黑格子,他会在
答案
设
总结
大力分讨+一定思维含量的推式子以及容斥。
坑点
首先在计算的时候所有减法一定要和
然后就是经典问题,一定记得取模!
代码
#include <bits/stdc++.h>
#define int long long
#define double long double
#define mid ((l+r+1)>>1)
using namespace std;
const int mod=1e9+7;
const int mul=1e9+2;
int n,m,k,t;
map<int,int> mp;
bool ok(int x,int y){
if(x<1||y<1||x>n||y>m) return false;
if(mp[x*mul+y]) return false;
return true;
}
signed main(){
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--){
cin>>n>>m>>k>>t;
mp.clear();
int nr=n*(m-1)+(n-1)*m,nr2=(n-1)*(m-1)*4+n*max(0ll,m-2)+m*max(0ll,n-2);
for(int i=1;i<=t;i++){
int x,y;
cin>>x>>y;
if(ok(x-1,y)) nr--;
if(ok(x+1,y)) nr--;
if(ok(x,y-1)) nr--;
if(ok(x,y+1)) nr--;
if(ok(x+1,y)&&ok(x,y+1)) nr2--;
if(ok(x+1,y)&&ok(x,y-1)) nr2--;
if(ok(x-1,y)&&ok(x,y+1)) nr2--;
if(ok(x-1,y)&&ok(x,y-1)) nr2--;
if(ok(x+1,y)&&ok(x+1,y+1)) nr2--;
if(ok(x+1,y)&&ok(x+1,y-1)) nr2--;
if(ok(x-1,y)&&ok(x-1,y+1)) nr2--;
if(ok(x-1,y)&&ok(x-1,y-1)) nr2--;
if(ok(x,y+1)&&ok(x-1,y+1)) nr2--;
if(ok(x,y+1)&&ok(x+1,y+1)) nr2--;
if(ok(x,y-1)&&ok(x-1,y-1)) nr2--;
if(ok(x,y-1)&&ok(x+1,y-1)) nr2--;
if(ok(x+1,y)&&ok(x-1,y)) nr2--;
if(ok(x,y+1)&&ok(x,y-1)) nr2--;
if(ok(x+1,y)&&ok(x+2,y)) nr2--;
if(ok(x-1,y)&&ok(x-2,y)) nr2--;
if(ok(x,y+1)&&ok(x,y+2)) nr2--;
if(ok(x,y-1)&&ok(x,y-2)) nr2--;
mp[x*mul+y]=1;
}
nr%=mod,nr2%=mod;
int tot=(n*m-t)%mod;
int num2=(tot*(tot-1)/2)%mod;
int num3=(tot*(tot-1)%mod*(tot-2)%mod*166666668)%mod;
if(k==2) cout<<(num2+mod-nr)%mod<<endl;
else cout<<(num3+mod-nr*max(tot-2,0ll)%mod+nr2)%mod<<endl;
}
return 0;
}