Description
Cyael is a very gifted girl who loves Magic (she even reached the finals on a very famous tournament in Byteland ;) ) and Computer Science. As we know, CS is a very vast subject and Cyael learns what she can, little by little, by reading the editorials of codechef.com, her favourite programming website.
Today, she came across a problem that was about calculating powers of two, and she got bored of it really fast, as she considers she knows all there is to know about powers of two. She knows how to compute even very big powers, like powers of 10, so it's obvious that for her, powers of two have no secrets :D
But her friend Lira, as she was tired of hearing her boasting about her skills for calculating powers, decided to challenge her with a brand new task: computing what she calls, SuperPowers of 2 .
Cyael: "Okay Lira, tell me about SuperPower of 2 so that I can solve one more problem and prepare for Codechef's November Long Challenge!! It's less than a month away!"
Lira: "I define the Nth Superpower of 2 as being the number (2N_bin)2 , where N_bin stands for the decimal number encoded by the representation in base 2 of the number N.
So, for example, the 2nd SuperPower of 2 is then equal to the number:
(210)2 = 1048576
because, N = 2 , and its binary encoding is 10 in decimal it is ten. So 210 = 1024 and 10242 = 1048576
Since the answer can be large, you are asked to compute SuperPowers of 2 modulo 1000000007."
After some time, Cyael finally solved the problem and decided to call Lira:
Cyael: "Well, I admit I struggled more than I'd have expected on this problem... You should consider becoming a problem setter and set this problem for Codechef... Do you want me to call Bruno and ask him to set this problem on your behalf? He always finds a way of writing a fun problem statement!!"
Lira: "Wooow!! That means Codechef community would solve my problem, modified by Bruno himself? Please do so, I'd love it!!!"
And now, here I am (yes, Bruno :D ) setting Lira's problem to all of you, but, with some differences regarding Lira's initial version, which hopefully you will appreciate.
Input
The first line of the input contains an integer T denoting the number of test cases.
Then on the following T lines, there is an integer N, denoting the index of the SuperPower of 2 you need to compute modulo 1000000007.
Output
For each test case, output a single line containing the required value: the Nth SuperPower of 2 modulo1000000007.
Constraints
Note: Your code will be judged against several input files.
Example
Input:
100000 1 2 (and 99998 more test cases...)
Output: 4 1048576 (and 99998 more answers...)
Analyse
This question wants us to calculate (2n)2. Yes, it is simple at the first look.
But n is not that simple just n, in this context, we should convert n to its binary format (n)2, and take (n)2 as a decimal number.
Such as (2)10=(10)2, then if n = 2, we should calculate 210*2=20, the maximum n = 600000, its binary format is 1001 0010 0111 1100 0000, and its length is 20. So large a number! So we should use some method to lower its power.
We can prove p = 1000000007 is a prime number, so according to Fermat's Little Theorem, we can get
2n' % p = 2(n' % (p - 1)) % p.
Code
1 /* 2 * References : www.codechef.com/NOV13/problems/SPOTWO/ 3 * Idea : Fermat's little theorem 4 */ 5 #include <cstdio> 6 7 typedef unsigned long long ll; 8 9 using namespace std; 10 11 const ll mod = 1000000007; 12 13 int len = 0; 14 ll pow2[65]; 15 ll rec2[65]; 16 ll str[32]; 17 18 inline void intTochar(ll x) 19 { 20 len = 0; 21 while(x > 0) 22 { 23 str[len] = x & 1; 24 len = len + 1; 25 x >>= 1; 26 } 27 } 28 29 inline ll lowPow() 30 { 31 int i = 0; 32 ll x = 0; 33 for(x = 0, i = len - 1; i >= 0; i--) 34 { 35 x = x * 10 + str[i]; 36 } 37 x = x % (mod - 1); // Fermat's little theorem 38 return x; 39 } 40 41 inline ll iPow(ll n) 42 { 43 int i = 64; 44 ll ret = 1; 45 while(n > 0) 46 { 47 for(; i >= 0; i--) 48 { 49 if(n >= rec2[i]) 50 { 51 n -= rec2[i]; 52 ret = (ret * pow2[i]) % mod; 53 break; 54 } 55 } 56 i = i + 1; 57 } 58 return ret; 59 } 60 61 int main() 62 { 63 int t = 0; 64 int i = 0; 65 ll n = 0; 66 67 pow2[0] = 1; 68 pow2[1] = 2; 69 70 rec2[0] = 0; 71 rec2[1] = 1; 72 73 for(i = 2; i < 65; i++) 74 { 75 pow2[i] = (pow2[i - 1] * pow2[i - 1]) % mod; 76 rec2[i] = rec2[i - 1] << 1; 77 } 78 79 scanf("%d", &t); 80 81 for(i = 1; i <= t; i++) 82 { 83 scanf("%llu", &n); 84 intTochar(n); 85 n = lowPow(); 86 n = iPow(n * 2); 87 printf("%llu\n", n); 88 } 89 return 0; 90 }