Codeforces 894.B Ralph And His Magic Field

B. Ralph And His Magic Field
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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 nm 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的方格,每个格子里只能填1或-1,要求最后每一列的数的乘积和每一行的数的乘积都等于k,问有多少种方案数.

分析:非常巧妙的思想.每放一个数都会对当前行和列造成影响,于是就要在当前行和当前列的其它位置放数来消除影响.因为最后的结果只有-1和1两种,所以为了消除影响只需要放一个数就行了,那么把消除影响的数放在最后一行或最后一列.那么前n-1行和前m-1列就可以随便放了,只需要在最后一行和最后一列调整到题目的要求就行了.但是这样会不会使得最后一行或最后一列不合法呢?答案是不会,分类讨论一下:如果k=1,有两个-1放在了不同行和不同列,那么不会造成不合法,因为同时补一个-1就能使得最后一行和最后一列的正负性相同.如果两个-1放在了同一行或同一列,那么最后一行和最后一列中一定有一个放了2个-1,另外一个放1,正负性还是不变,所以不会使得最后一行或最后一列不合法.但是有个特例:n+m %2 = 1并且k=-1是一定没有合法的方案的.因为每一行要放奇数个-1,总共有奇数行,那么要放奇数个-1,每一列要放奇数个-1,总共有偶数列,那么要放偶数个-1,矛盾了,所以没有合法的方案,特判一下就可以了.

          打表也挺容易找到规律.get一个新技巧,以前处理这种行列有影响的题都是先处理行再来处理列,消除影响,这道题可以把行列的决定权交给最后的行列来处理.正负性往往和奇偶性有关,一定要注意检验是否每一种奇偶性都满足推导.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>
#include <algorithm>

using namespace std;

const int mod = 1e9 + 7;

typedef long long ll;

ll n, m, k, ans;

ll qpow(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
            res = (res * a) % mod;
        a = (a * a) % mod;
        b >>= 1;
    }
    return res % mod;
}

int main()
{
    cin >> n >> m >> k;
    if ((n + m) % 2 == 1 && k == -1)
        ans = 0;
    else
        ans = qpow(2, ((n - 1) % (mod - 1)) * ((m - 1) % (mod - 1)));
    cout << ans % mod << endl;

    return 0;
}

 

 

posted @ 2017-12-13 16:12  zbtrs  阅读(321)  评论(0编辑  收藏  举报