题目链接:http://codeforces.com/contest/894/problem/B
题目大意:
往一个 (n imes m) 的网格中填数字 ((1 le n,m le 10^{18})),使得网格的任意一行和任意一列的乘积均为 (k (k in {-1, 1}).)问有多少种方案。
知识点: 费马小定理、快速幂
解题思路:
1、网格中的数字,要么是 1,要么是 -1;
2、如果网格中 ((n-1) imes (m-1)) 的子网格上的数字已经确定,那么最后一行和最后一列上的数字也随之确定,整个网格亦即随之确定,因此填数字的方案数为 (2^{(n-1)(m-1)}). 要理解这个结论为什么成立,可以试着想象:当网格中 ((n-1) imes (m-1)) 的子网格上填满 1(此时最后一行和最后一列也已经确定),如果改变子网格上的数字,只要随之改变外层的数字即可。但是,在一种情况下答案为 0 :当 (k = -1) 并且 n 和 m 的奇偶性不同时。对于这一点,我们可以这么分析:
假设 (k = -1, n = 1, m = 2x (x in N)),答案显然为 0;
则 (k = -1, n = 2, m = 2x + 1 (x in N)),答案为 0;
由此类推,(k = -1, n = 1 + y, m = 2x + y (x, y in N)),答案亦为 0.
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 typedef long long ll; 6 const ll mod = 1000000007; 7 8 ll Fast_Power(ll t){//快速幂 9 ll ret=1; 10 ll a=2; 11 while(t){ 12 if(t&1) ret=ret*a%mod; 13 t>>=1; 14 a=a*a%mod; 15 } 16 return ret; 17 } 18 int main() 19 { 20 ll n,m; 21 int k; 22 scanf("%lld%lld%d",&n,&m,&k); 23 if(k==-1&&(n%2!=m%2)) 24 printf("0 "); 25 else{ 26 ll ans=Fast_Power(((n-1)%(mod-1))*((m-1)%(mod-1))%(mod-1))%mod;//此处应用费马小定理 27 printf("%lld ",ans); 28 } 29 return 0; 30 }