I know that pow(base, power) is a built-in function in C with complexity O(power). Can I reduce the complexity of it by dynamic programming?
You can calculate it in O(logn)
int power(int x, unsigned int y)
{
int temp;
if( y == 0)
return 1;
temp = power(x, y/2);
if (y%2 == 0)
return temp*temp;
else
return x*temp*temp;
}
Details in Here
If your input arguments are non-negative integers, then you can implement your own pow.
Iteratively, with running time = O(n):
unsigned long long pow(unsigned long long x,unsigned int n)
{
unsigned long long res = 1;
while (n--)
res *= x;
return res;
}
Recursively, with running time = O(n):
unsigned long long pow(unsigned long long x,unsigned int n)
{
if (n == 0)
return 1;
if (n == 1)
return x;
return pow(x,n/2)*pow(x,n-n/2);
}
Efficiently, with running time = O(log(n)):
unsigned long long pow(unsigned long long x,unsigned int n)
{
unsigned long long res = 1;
while (n > 0)
{
if (n & 1)
res *= x;
n >>= 1;
x *= x;
}
return res;
}
Related
I'm trying to submit this leetcode problem Pow(x,n) using iterative approach.
double poww(double x, int n)
{
if (n == 0)
return 1;
double ans = 1;
double temp = x;
while (n)
{
if (n & 1)
{
ans *= temp;
}
temp *= temp;
n = (n >> 1);
}
return ans;
}
double myPow(double x, int n)
{
if (n == 0)
return 1.0;
if (n < 0)
return 1 / poww(x, abs(n));
return poww(x, n);
}
This code is giving time limit exceed error but when I change the right shift operator >> with normal division operator, the code works just fine.
Working code with division operator
double poww(double x, int n)
{
if (n == 0)
return 1;
double ans = 1;
double temp = x;
while (n)
{
if (n & 1)
{
ans *= temp;
}
temp *= temp;
n /= 2;
}
return ans;
}
double myPow(double x, int n)
{
if (n == 0)
return 1.0;
if (n < 0)
return 1 / poww(x, abs(n));
return poww(x, n);
}
I don't know what I'm missing here.
The problem is the given input range for "n".
Let us look at the constraints again:
The problem is the smallest number for n, which is -2^31 and that is equal to -2147483648.
But the valid range for an integer is -2^31 ... 2^31-1 which is -2147483648 ... 2147483647.
Then you try to use the abs function on -2147483648. But since there is no positive equivalent for that in the integer domain (on your machine), the number stays negative. And then you get the wrong result, because your n will be negative in your "poww" function.
Presumably on your machine long is the same as int, so, a 4 byte variable. If you change your interface to use a long long variable, it will work. Result maybe "inf" for big numbers or 0.
Please check the below code:
#include <iostream>
#include <cmath>
long double poww(double x, long long n)
{
if (n == 0)
return 1;
long double ans = 1;
long double temp = x;
while (n)
{
if (n & 1)
{
ans *= temp;
}
temp *= temp;
n = (n >> 1);
}
return ans;
}
long double myPow(double x, long long n)
{
if (n == 0)
return 1.0;
if (n < 0)
return 1 / poww(x, std::llabs(n));
return poww(x, n);
}
int main() {
std::cout << myPow(1, -2147483648) << '\n';
}
I'm a computer science student and i have a problem where i must use the fast modular exponentation.
With this code that i made, the corrector says me that the output in some cases is incorrect, but it shouldn't be.
unsigned long long int pow(int a, int n, int M)
{
if(n==0)
return 1;
if(n==1)
return a;
unsigned long long tmp=pow(a, n/2, M)%M;
if(n%2==0)
return ((tmp)*(tmp))%M;
return ((tmp*tmp)*(a%M))%M;
}
Instead with this other code i pass all the test cases.
unsigned long long int pow(int a, int n, int M)
{
if(n==0)
return 1;
if(n==1)
return a;
unsigned long long tmp;
if(n%2==0){
tmp=pow(a, n/2, M)%M;
return (tmp*tmp)%M;
}
tmp=pow(a, n-1, M)%M;
return (tmp*(a%M))%M;
}
So my question is why with the first code i don't pass all the test cases?
First, if n == 1, the return value should be a % M, not a. Second, the product (tmp * tmp) * (a % M) can overflow, and should be computed as ((tmp * tmp) % M) * (a % M).
The condition n == 1 doesn't need any special treatment, and the code can be simplified to:
unsigned long long int pow(unsigned int a, unsigned int n, unsigned int m) {
if (n == 0)
return 1;
auto tmp = pow(a, n / 2, m) % m;
tmp *= tmp;
if (n % 2)
tmp = (tmp % m) * (a % m);
return tmp % m;
}
I'm a newbie to this contest and it is the first time participating. I have two questions to ask.
I downloaded input and it has aa.in format (I never saw this kind of format :p). Then should I make output as aa.out format or can I just use aa.txt format? And if I need to make aa.out format, then how can I make it? Just redirect it using > aa.out?
I tried to solve this problem (https://code.google.com/codejam/contest/dashboard?c=4384486#s=p2) and it worked well for the sample cases but when I submit it is incorrect. At the beginning it showed some negative numbers for some cases which should not happen. Thus, I debugged it not to have them by converting int to long long and put some modular. However, I still can't get the answer while I don't know why. Therefore, I need some help figuring out what's going wrong here. If you give me even a hint, it will be very helpful!
#include <stdio.h>
#include <iostream>
using namespace std;
void makeFullArray(unsigned long long * full, unsigned long long arrlen, unsigned long long x1, unsigned long long y1, unsigned long long C, unsigned long long D, unsigned long long E1, unsigned long long E2, unsigned long long F)
{
unsigned long long prevx = x1;
unsigned long long prevy = y1;
unsigned long long x, y;
for (unsigned long long i = 2; i <= arrlen; i++)
{
x = (C * prevx + D * prevy + E1) % F;
y = (D * prevx + C * prevy + E2) % F;
full[i] = (x + y) % F;
prevx = x;
prevy = y;
}
}
unsigned long long exponential(unsigned long long base, unsigned long long exp)
{
unsigned long long res = 1;
while (exp)
{
if (exp & 1)
res *= base;
exp >>= 1;
base *= base;
}
return res;// (res % (1000000000 + 7));
}
void getexponential(unsigned long long * temp, unsigned long long cnt, unsigned long long * result, unsigned long long K, unsigned long long n)
{
unsigned long long mod = 1000000007;
for (unsigned long long j = 1; j <= K; j++)
{
for (unsigned long long i = 0; i < cnt; i++)
{
result[j] += ((temp[i] * exponential(i + 1, j)) % mod);
}
}
printResult(result, K);
}
void calculate(unsigned long long n, unsigned long long * full, unsigned long long * result, unsigned long long K)
{
for (unsigned long long i = 1; i <= n; i++)
{
unsigned long long multiplier = i;
unsigned long long cnt = 0;
unsigned long long temp[102] = { 0 };
for (unsigned long long j = 1; j < n; j++)
{
temp[cnt] = full[j];
cnt++;
if (cnt == multiplier)
{
//cout << cnt << " -- " << endl;
getexponential(temp, cnt, result, K, n);
j = j - cnt + 1;
if (n - j < multiplier)
break;
cnt = 0;
}
}
}
}
unsigned long long getsum(unsigned long long * result, unsigned long long K)
{
unsigned long long tmp = 0;
unsigned long long mod = 1000000007;
for (unsigned long long i = 1; i <= K; i++)
{
tmp += (result[i] % (mod));
tmp %= mod;
}
return tmp;
}
int main(void)
{
int TC;
scanf_s("%d", &TC);
for (int i = 1; i <= TC; i++)
{
unsigned long long N, K, x1, y1, C, D, E1, E2, F;
scanf_s("%llu %llu %llu %llu %llu %llu %llu %llu %llu", &N, &K, &x1, &y1, &C, &D, &E1, &E2, &F);
unsigned long long full[101];
unsigned long long result[21] = { 0 };
full[1] = (x1 + y1)%F;
// figure out the given array A
makeFullArray(full, N, x1, y1, C, D, E1, E2, F);
// calculate for each exponential power
calculate(N+1, full, result, K);
// sum over the range K to get the answer
unsigned long long tot = getsum(result, K);
cout << "Case #" << i << ": " << (tot%(1000000007L)) << endl;
}
return 0;
}
You can download other contestants answers and run them on the same inputs, and see where your answers differ. That might give you some clues.
How can I calculate (a ^ b) % c, where 0 <= a, b, c <= 10^18.
Here, (a ^ b) means a to the power b, not a xor b.
My current code for the problem is:
unsigned long long bigMod(unsigned long long b,
unsigned long long p,
unsigned long long m){
if(b == 1) return b;
if(p == 0) return 1;
if(p == 1) return b;
if(p % 2 == 0){
unsigned long long temp = bigMod(b, p / 2ll, m);
return ((temp) * (temp) )% m;
}else return (b * bigMod(b, p-1, m)) % m;
}
For this input:
a = 12345 b = 123456789 and c = 123456789012345
the expected output should be:
59212459031520
You have a problem with temp*temp (long long overflow). You can omit this problem using algorithm of fast mod power to multiply them mod m. Here You have working code:
unsigned long long bigMultiply(unsigned long long b,unsigned long long p, unsigned long long m)
{
if(p == 0 )return b;
if(p%2 == 0)
{
unsigned long long temp = bigMultiply(b,p/2ll,m);
return ((temp)+(temp))%m;
}
else
return (b + bigMultiply(b,p-1,m))%m;
}
unsigned long long bigMod(unsigned long long b,unsigned long long p, unsigned long long m)
{
if(b == 1)
return b;
if(p == 0 )return 1;
if( p == 1)return b;
if(p%2 == 0)
{
unsigned ll temp = bigMod(b,p/2ll,m);
return bigMultiply(temp,temp,m);
}
else
return (b * bigMod(b,p-1,m))%m;
}
I use this code in c++:
long long power(long long a, long long b, long long c)
{
if (b==0)
{
return 1;
}
if (b % 2 == 0)
{
long long w = power(a, b/2, c);
return (w*w) % c;
}
else
{
int w = power(a, b-1, c);
return (a*w) % c;
}
}
It has logarithmic complexity.
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
void mul ( long long f[2][2], long long m[2][2] );
void power (long long f[2][2], long long int n );
int fibo (long long int n);
int main (void)
{
int c;
cin>>c;
while (c!= 0)
{
int n,val;
cin>>n;
val = fibo(n);
cout<<val<<"\n";
c--;
}
return 0;
}
int fibo (long long int n)
{
long long f[2][2] = {{1,1},{1,0}};
if ( n == 0 )
return 0;
else
power(f,n-1);
return f[0][0];
}
void power (long long f[2][2], long long int n )
{
if ( n == 0 )
return;
long long m[2][2] = {{1,1},{1,0}};
if ( n % 2 == 0 )
{
mul(f,f);
power(f,n/2);
}
else
{
mul(f,f);
mul(f,m);
power(f,(n-1)/2);
}
}
void mul ( long long f[2][2], long long m[2][2] )
{
long long x = f[0][0]*m[0][0] + f[0][1]*m[1][0];
long long y = f[0][0]*m[0][1] + f[0][1]*m[1][1];
long long z = f[1][0]*m[0][0] + f[1][1]*m[1][0];
long long w = f[1][0]*m[0][1] + f[1][1]*m[1][1];
f[0][0] = x;
f[0][1] = y;
f[1][0] = z;
f[1][1] = w;
}
I made this code using the matrix exponentiation by squaring method. However, I am not getting the right answer. Why is that?
Why am I not getting the correct output for the Fibo number for this? I am getting the output as
3rd Term: 8
4th Term: 21
5th Term: 55
6th Term: 377
Why is this happeining? I tried using the debugger but I am not able to spot the error.
The power(...) function looks buggy. How about this:
void power (long long f[2][2], long long int n )
{
if ( n == 1 || n == 0 ) // if n == 1, the matrix f^1 should be kept untouched.
return; // if n == 0, f should be an identity. it is
// a special case here because of your divide-and-
// conquer logic.
long long m[2][2] = {{1,1},{1,0}};
if ( n % 2 == 0 )
{
power(f,n/2); // given f = m^(n/2) is ready
mul(f,f); // m^n = m^(n/2) x m^(n/2)
}
else
{
power(f,(n-1)/2); // given f = m^((n-1)/2) is ready
mul(f,f); // m^(n-1) = m^((n-1)/2) x m^((n-1)/2)
mul(f,m); // m^n = m^(n-1) x m
}
}