NOIP 模擬 $25\; \rm queen$
阿新 • • 發佈:2021-07-31
題解
題解 \(by\;zj\varphi\)
這是一道純分類討論,然後推式子的題,細節挺多,挺麻煩,但是很考驗數學能力
不講了,官方題解給的很清楚
Code:
%: pragma GCC optimize("O9") #include<bits/stdc++.h> #define ri register signed #define p(i) ++i using namespace std; namespace IO{ char buf[1<<21],*p1=buf,*p2=buf,OPUT[100]; #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++ template<typename T>inline void read(T &x) { ri f=1;x=0;register char ch=gc(); while(!isdigit(ch)) {if (ch=='-') f=0;ch=gc();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=gc();} x=f?x:-x; } template<typename T>inline void print(T x,char t) { if (x<0) putchar('-'),x=-x; if (!x) return putchar('0'),(void)putchar(t); ri cnt(0); while(x) OPUT[p(cnt)]=x%10,x/=10; for (ri i(cnt);i;--i) putchar(OPUT[i]^48); return (void)putchar(t); } } using IO::read;using IO::print; namespace nanfeng{ #define FI FILE *IN #define FO FILE *OUT #define int long long template<typename T>inline T cmax(T x,T y) {return x>y?x:y;} template<typename T>inline T cmin(T x,T y) {return x>y?y:x;} static const int MOD=3e5+7; int frac[MOD+7],inv[MOD+7],n,m,k,T,ans,bs1,bs2; inline int fpow(int x,int y) { int res(1); while(y) { if (y&1) res=res*x%MOD; x=x*x%MOD; y>>=1; } return res; } inline void init() { bs1=fpow(2,MOD-2),bs2=fpow(3,MOD-2); frac[1]=1; for (ri i(2);i<=MOD-1;p(i)) frac[i]=frac[i-1]*i%MOD; inv[MOD-1]=fpow(frac[MOD-1],MOD-2); for (ri i(MOD-2);i;--i) inv[i]=inv[i+1]*(i+1)%MOD; } inline int C(int n,int m) { if (n<m) return 0; if (n==m||!m) return 1; return frac[n]*inv[n-m]%MOD*inv[m]%MOD; } int lucas(int n,int m) { if (n<m) return 0; if (n==m||!m) return 1; return C(n%MOD,m%MOD)*lucas(n/MOD,m/MOD)%MOD; } inline int MD(int &x) {return x=x>=MOD?x-MOD:x;} inline int solve0() { int tmp1=(lucas(n,k)*(m%MOD)%MOD+lucas(m,k)*(n%MOD)%MOD)%MOD; int tmp2=(2*lucas(m+1,k+1)+2*lucas(m,k)*((n-m)%MOD)%MOD+2*lucas(m,k+1)%MOD)%MOD; return (tmp1+tmp2)>=MOD?(tmp1+tmp2)-MOD:tmp1+tmp2; } inline int calc1(int x) {return bs2*x*(x+1)%MOD*(x+bs1)%MOD;} inline int calc2(int x) {return (x*(x+1)>>1ll)%MOD;} inline int solve1() {return (n%MOD)*(m%MOD)%MOD;} inline int solve3() { int x=(cmin(n+1,(m+2)>>1)-1)%MOD; int y=(cmin(m+1,(n+2)>>1)-1)%MOD; n%=MOD,m%=MOD; int tmp1=2*(n*m*(x+y)%MOD+2*(calc1(x)+calc1(y))%MOD-(2*n+m)*calc2(x)%MOD-(2*m+n)*calc2(y)%MOD+MOD)%MOD; int tmp2=4*(n*m%MOD*(m-1)%MOD+calc1(m-1)-(n+m)*calc2(m-1)%MOD+MOD)%MOD; return (tmp1+tmp2+MOD)%MOD; } inline int solve4() { int x=(cmin(n+1,(m+2)>>1)-1)%MOD; int y=(cmin(m+1,(n+2)>>1)-1)%MOD; int z=(m>>1)%MOD; n%=MOD,m%=MOD; int tmp1=2*(n*m%MOD*(x+y)%MOD+2*(calc1(x)+calc1(y))%MOD-(2*n+m)*calc2(x)%MOD-(2*m+n)*calc2(y)%MOD+MOD)%MOD; int tmp2=(n*m%MOD*(m-1)%MOD+calc1(m-1)-(n+m)*calc2(m-1)%MOD+MOD)%MOD; int tmp3=5*(n*m*z%MOD-2*(n+m)*calc2(z)%MOD+4*calc1(z)+MOD)%MOD; return (tmp1+tmp2+tmp3+MOD)%MOD; } inline int solve5() { int x=(m-1>>1)%MOD; n%=MOD,m%=MOD; int tmp=(2*n*m*x%MOD+8*calc1(x)%MOD-4*(n+m)*calc2(x)%MOD+MOD)%MOD; return tmp; } inline int main() { //FI=freopen("nanfeng.in","r",stdin); //FO=freopen("nanfeng.out","w",stdout); init(); read(T); for (ri z(1);z<=T;p(z)) { ans=0; read(n),read(m),read(k); if (n<m) swap(n,m); if (k>1) ans=solve0(); switch(k) { case 1:ans=solve1(),MD(ans);break; case 3:ans+=solve3(),MD(ans);break; case 4:ans+=solve4(),MD(ans);break; case 5:ans+=solve5(),MD(ans);break; default:break; } print(ans,'\n'); } return 0; } #undef int } int main() {return nanfeng::main();}