CF894B Ralph And His Magic Field

题目链接: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 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/7905973.html