题意:在n×mn\times mn×m的矩阵上面放kkk个皇后使得所有皇后都能互相攻击。不同于正常打法的一点是这里面的皇后能无视阻挡攻击。
这里面的n,mn,mn,m和kkk的范围都极大无比,不可能考虑枚举。
考虑到一个皇后瞄准的位置,想让所有的皇后互相攻击,按照皇后的攻击方式来看:如果kkk达到666或更高,那么显然只能让所有皇后都在一条直线上。所以就只需要考虑k≤5k\leq5k≤5的时候怎么做。
k=1k=1k=1
直接输出矩阵大小即可。
k=2k=2k=2
和k>5k>5k>5的时候的放置方法一致。
考虑横向放置,答案就是n×∑i=km(im)n\times \sum^m_{i=k}{i\choose m}n×∑i=km(mi)
竖向放置类似。
斜向呢?斜着看的话长度应该是分三段排布:
- k,k+1,k+2……k,k+1,k+2……k,k+1,k+2……直到min(n,m)\min(n,m)min(n,m)
- min(n,m),min(n,m),……\min(n,m),\min(n,m),……min(n,m),min(n,m),……这样max(n,m)−min(n,m)+1\max(n,m)-\min(n,m)+1max(n,m)−min(n,m)+1个
- min(n,m),min(n,m)−1,min(n,m)−2,……\min(n,m),\min(n,m)-1,\min(n,m)-2,……min(n,m),min(n,m)−1,min(n,m)−2,……这样直到kkk
剩下的全部是无效段。
如何计算?考虑上指标求和:(1n)+(2n)+(3n)+……+(mn)=(m+1n+1){1\choose n}+{2\choose n}+{3\choose n}+……+{m\choose n}={m+1\choose n+1}(n1)+(n2)+(n3)+……+(nm)=(n+1m+1),利用该公式即可。
k=3k=3k=3
相对于第二种情况只多了两种特殊的情况:
如何计算?最原始的方法:枚举右下角。
∑i=1n∑jmmin(i,j)−1 \sum^n_{i=1}\sum^m_j\min(i,j)-1 i=1∑nj∑mmin(i,j)−1
考虑如何优化?
还是上指标求和。
把矩阵打表打出来看看。
[00000000011111110122222201233333012344440123455501234566] \begin{bmatrix}0&0&0&0&0&0&0&0\\ 0&1&1&1&1&1&1&1\\ 0&1&2&2&2&2&2&2\\ 0&1&2&3&3&3&3&3\\ 0&1&2&3&4&4&4&4\\ 0&1&2&3&4&5&5&5\\ 0&1 &2&3&4&5&6&6\end{bmatrix} ⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡00000000111111012222201233330123444012345501234560123456⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤
考虑这个怎么计算?除去没用的000,发现剩下的东西可以看做两个三角形叠在一起加上一个小矩形,这些都是可以简单算出来的。
利用上指标求和即可:2×(n+13)+(m−n−1)×n×(n−1)22\times {n+1\choose3}+\dfrac{(m-n-1)\times n\times(n-1)}{2}2×(3n+1)+2(m−n−1)×n×(n−1)(假设n<mn<mn<m)
考虑一下翻转,结果乘个444即可。
另一种情况:
∑i=1n∑j=1mmin(i−1,j−12) \sum^{n}_{i=1}\sum^{m}_{j=1}\min(i-1,\frac{j-1}{2}) i=1∑nj=1∑mmin(i−1,2j−1)
这种情况也类似。
[0000000001111100112220011223] \begin{bmatrix}0&0&0&0&0&0&0\\ 0&0&1&1&1&1&1\\0&0&1&1&2&2&2\\0&0&1&1&2&2&3\end{bmatrix} ⎣⎢⎢⎡0000000001110111012201220123⎦⎥⎥⎤
考虑压缩一下列,然后再额外算一下最后一列即可。
式子和上面类似。
考虑k=4k=4k=4
多了以下方案:
第一种和k=3k=3k=3第二种无异。
第二种和第三种都可以看作长度为奇数的正方形。忽略长度为111的即可。
矩阵内部怎么数奇数正方形个数?
假设n<mn<mn<m
按照nnn的奇偶性推算。
奇数:
(n−2)×(m−2)+(n−4)×(m−4)+……+(n−(n−1))+(m−(n−1))=(n−1)2×n×m−n2−14×(n+m)+(n−1)×n×(n+1)6 (n-2)\times (m-2)+(n-4)\times (m-4)+……+(n-(n-1))+(m-(n-1)) \\ =\dfrac{(n-1)}{2}\times n\times m-\dfrac{n^2-1}{4}\times (n+m)+\dfrac{(n-1)\times n\times (n+1)}{6} (n−2)×(m−2)+(n−4)×(m−4)+……+(n−(n−1))+(m−(n−1))=2(n−1)×n×m−4n2−1×(n+m)+6(n−1)×n×(n+1)
偶数:
(n−2)×(m−2)+(n−4)×(m−4)+……+(n−(n−2))+(m−(n−2))=n2×n×m−n2−2×n4×(n+m)+(n−2)×(n−1)×n6 (n-2)\times (m-2)+(n-4)\times (m-4)+……+(n-(n-2))+(m-(n-2)) \\ =\dfrac{n}{2}\times n\times m-\dfrac{n^2-2\times n}{4}\times (n+m)+\dfrac{(n-2)\times (n-1)\times n}{6} (n−2)×(m−2)+(n−4)×(m−4)+……+(n−(n−2))+(m−(n−2))=2n×n×m−4n2−2×n×(n+m)+6(n−2)×(n−1)×n
最后就是边长为任意长度的正方形。
式子:
(n−1)×n×m−n×(n−1)2×(n+m)+n×(n−1)×(2×n−1)6 (n-1)\times n\times m-\dfrac{n\times (n-1)}{2}\times(n+m)+\dfrac{n\times (n-1)\times (2\times n-1)}{6} (n−1)×n×m−2n×(n−1)×(n+m)+6n×(n−1)×(2×n−1)
k=5k=5k=5?
只有两种情况。
其实早已解决。
就是找矩形内的奇数正方形。
code:code:code:
#include <bits/stdc++.h>
#define int long long
#define regi register long long
#define mod 300007
int q,n,m,k;
int jc[1000001],inv[1000001];
inline int read(){
int r=0,w=0,c;
for(;!isdigit(c=getchar());r=c);
for(w=c^48;isdigit(c=getchar());w=w*10+(c^48));
return r^45?w:-w;
}
inline long long add(long long x,long long y){
x%=mod;
y%=mod;
return (x+=y)>=mod?x-mod:x;
}
inline long long addself(long long &x,long long y){
return x=add(x,y);
}
inline long long dec(long long x,long long y){
x%=mod;
y%=mod;
return (x-=y)<0?x+mod:x;
}
inline long long decself(long long &x,long long y){
return x=dec(x,y);
}
inline long long mul(long long x,long long y){
x%=mod;
y%=mod;
return x*y%mod;
}
inline long long mulself(long long &x,long long y){
return x=mul(x,y);
}
inline long long C(long long x,long long y){
if(!x)
return 1;
if(y<x)
return 0;
if(x<mod&&y<mod)
return mul(jc[y],mul(inv[x],inv[y-x]));
if(y>=mod||x>=mod)
return mul(C(x%mod,y%mod),C(x/mod,y/mod));
}
inline long long ksm(long long x,long long y,long long z=1){
for(;y;mulself(z,y&1?x:1),y>>=1,mulself(x,x));
return z%mod;
}
inline long long solve1(){
long long ans=0;
addself(ans,add(mul(n,C(k,m)),mul(m,C(k,n))));
addself(ans,add(mul(mul(2,(std::max(n,m)-std::min(n,m)+1)),C(k,std::min(n,m))),mul(4,C(k+1,std::min(n,m)))));
return ans;
}
inline long long matrix(int x,int y){
if(x>y)
std::swap(x,y);
return add(mul(2,C(3,x+1)),mul(y-x-1+mod,mul(x,mul(x-1,inv[2]))));
}
inline long long matrixt(int x,int y){
if(x>y)
std::swap(x,y);
return add(mul(2,add(matrix(n,m/2),matrix(n,m/2+m%2))),mul(2,add(matrix(m,n/2),matrix(m,n/2+n%2))));
}
inline long long odd_square(int x,int y){
if(x>y)
std::swap(x,y);
long long ans=0;
if(x&1){
addself(ans,mul(mul(x-1,ksm(2,mod-2)),mul(x,y)));
decself(ans,mul(mul(dec(mul(x,x),1),ksm(4,mod-2)),add(x,y)));
addself(ans,mul(mul(x,mul(dec(x,1),add(x,1))),ksm(6,mod-2)));
}
else{
addself(ans,mul(mul(dec(x,2),ksm(2,mod-2)),mul(x,y)));
decself(ans,mul(mul(mul(dec(x,2),x),ksm(4,mod-2)),add(x,y)));
addself(ans,mul(mul(x,mul(dec(x,1),dec(x,2))),ksm(6,mod-2)));
}
return ans;
}
inline long long all_square(int x,int y){
if(x>y)
std::swap(x,y);
long long ans=mul(mul(dec(x,1),x),y);
decself(ans,mul(mul(mul(x,dec(x,1)),ksm(2,mod-2)),add(x,y)));
addself(ans,mul(mul(x,mul(dec(x,1),dec(mul(2,x),1))),ksm(6,mod-2)));
return ans;
}
inline long long Solve3(){
if(k!=3)
return 0;
long long ans=0;
addself(ans,mul(4,matrix(n,m)));
addself(ans,matrixt(n,m));
return ans;
}
inline long long Solve4(){
if(k!=4)
return 0;
long long ans=0;
addself(ans,matrixt(n,m));
addself(ans,mul(5,odd_square(n,m)));
addself(ans,all_square(n,m));
return ans;
}
inline long long Solve5(){
if(k!=5)
return 0;
long long ans=mul(2,odd_square(n,m));
return ans;
}
main(){
jc[0]=1;
inv[0]=inv[1]=1;
for(regi i=1;i<=300007;++i)
jc[i]=mul(jc[i-1],i);
for(regi i=2;i<=300007;++i)
inv[i]=mul(dec(mod,mod/i),inv[mod%i]);
for(regi i=2;i<=300007;++i)
mulself(inv[i],inv[i-1]);
q=read();
while(q--){
n=read(),m=read(),k=read();
if(n>m)
std::swap(n,m);
if(k==1)
printf("%lld\n",mul(n,m));
else{
long long ans=solve1();
addself(ans,add(add(Solve3(),Solve4()),Solve5()));
printf("%lld\n",ans);
}
}
return 0;
}