Description
Ralph has a magic field which is divided into n × m blocks. That is to
say, there are n rows and m columns on the field. Ralph can put an
integer in each block. However, the magic field doesn’t always work
properly. It works only if the product of integers in each row and
each column equals to k, where k is either 1 or -1.Now Ralph wants you to figure out the number of ways to put numbers in
each block in such a way that the magic field works properly. Two ways
are considered different if and only if there exists at least one
block where the numbers in the first way and in the second way are
different. You are asked to output the answer modulo
1000000007 = 109 + 7.Note that there is no range of the numbers to put in the blocks, but
we can prove that the answer is not infinity.
Input
The only line contains three integers n, m and k (1 ≤ n, m ≤ 1018, k
is either 1 or -1).
Output
Print a single number denoting the answer modulo 1000000007.
Examples
input
1 1 -1
output
1
input
1 3 1
output
1
input
3 3 -1
output
16
Note
In the first example the only way is to put -1 into the only block.
In the second example the only way is to put 1 into every block.
思路
有一个
n∗m
的方格,要在里面填数字,使得每一行和每一列的乘积都为
k
,k的取值是1或者-1,问的是一共有几种填数的方法,结果很大要对1e9+7
取模
我们这样考虑,要在要
ans=2(n−1)∗(m−1)
但是我们要注意,当k的值是-1的时候,如果 (n+m) 的值是一个奇数,那么不论怎么填,都满足不了题目的要求,最后乘起来一定会出现1,所以当k为-1且 (n+m) 的值是一个奇数,就输出0
还要注意,因为n和m的值都可以到1e18,数字比较大,我们可以在快速幂的时候用一个技巧:
ans=(2n−1)m−1
这样就可以保证数据不爆,当然这是对于c++而言的,这怎么能难得住我们的大py呢!
代码1(c++)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1000+20;
const ll mod=1e9+7;
ll pow_mod(ll a,ll b,ll c)
{
a%=c;
ll ans=1;
while(b)
{
if(b&1)
ans=ans*a%c;
a=a*a%c;
b>>=1;
}
return ans;
}
int main()
{
ll n,m,k;
scanf("%lld%lld%lld",&n,&m,&k);
if(k==-1&&(n+m)&1)
puts("0");
else
printf("%lld\n",pow_mod(pow_mod(2,n-1,mod),m-1,mod));
return 0;
}
代码2(python3)
mod=int(1e9+7)
n,m,k=map(int,input().split())
if(k==-1 and (n+m)&1):
print('0')
else:
print(pow(2,(n-1)*(m-1),mod))