I want to calculate cos(nx) = p/q Using recursion and memoization so i tried Chebyshev Method for Recursive Method it works for small inputs of n but i want to do it for larger inputs like 10^18 etc. How should i approach it to calculate cos(nx) in p/q Form?
For larger Values of n i am getting Memory Problem How do i fix that?
cos(x) = a/b Known
#include <bits/stdc++.h>
using namespace std;
map<long, long> numerator;
map<long, long> denominator;
#define MODULO 1000000007
long a, b, n;
int main() {
cin >> a >> b;
cin >> n;
numerator[0] = 1;
numerator[1] = a;
denominator[0] = 1;
denominator[1] = b;
for (long i = 2; i <= n; ++i) {
numerator[i] = (long) (2 * a * numerator[i - 1] - b*numerator[i - 2]) % MODULO;
denominator[i] = (denominator[i - 1] * denominator[i - 2]) % MODULO;
}
cout << "numerator of cos(nx) = " << numerator[n] << " denominator = " << denominator[n] << endl;
}
lol Thats a contests question you're asking for. Shame on you. That's Codechef's February Challenge's Question. How low can you fall for some rating. smh
Related
Find a sum of series by function s= 1!/y!+y!/3!+5!/y!......n
I don't know how to define fact function and is this code correct??
#include <math.h>
#include <iostream>
using namespace std;
float fact(float, float);
float sum(float, float);
int main() {
float n, x, s;
cout << "enter n and x" << endl;
cin >> n >> x;
s = sum(n, x);
cout << "sum =" << s << endl;
return 0;
}
float sum(float n, float x)
{
float x, s = 0;
for (int i = 0; i <= n; i++)
if (i % 2 == 0)
s = s + float(fact(i + 1) / fact(x));
else
s = s + float(fact(x) / fact(i + 1));
return s;
}
Whilst there are ways of defining the factorial of a floating-point number (using a gamma function), I doubt that is what you want. Similarly, the upper index n shouldn't be a float, either.
Your series as written looks awfully divergent.
As somebody else has said, it is rare to calculate new factorials from scratch: divisors of them tend to cancel, and whole terms of your series are simple multiples of earlier terms.
This question already has answers here:
initialize array with stackoverflow error [duplicate]
(2 answers)
Finding out nth fibonacci number for very large 'n'
(24 answers)
Finding the fibonacci number of large number
(1 answer)
Closed 2 years ago.
I'm solving a CSES problem in which I've to find the sum of first 'n' Fibonacci numbers. The code:
#pragma GCC optimize("Ofast")
#include <iostream>
using namespace std;
int main()
{
unsigned long long int n;
scanf("%llu", &n);
unsigned long long int seq[n];
seq[0] = 0;
seq[1] = 1;
unsigned long long int mod = 1000000000 + 7;
for (unsigned long long int i = 2; i < n + 1; i++) {
seq[i] = (seq[i - 1] + seq[i - 2]) % mod;
}
cout << seq[n];
}
The problem specifies that the value of n can get upto 10^18 and therefore I have used unsigned long long int to initialize n. The problem also instructs to give the modulo 7 answer. The code is working fine for values of n upto 4 digits but breaks when the value of n rises to the upper ceiling of 10^18.It gives a (0xC00000FD) error and does not return anything. Please help me understand the problem here and how to deal with it. Any other suggestions would also be appreciated.
When doing modular addition, you need to apply your mod to each value you're adding.
For example, (a + b) % c = (a % c + b % c) % c.
That means in your code:
seq[i] = (seq[i - 1] % mod + seq[i - 2] % mod) % mod;
Otherwise, the addition of seq[i - 1] and seq[i - 2] will result in an overflow.
Read more about modular arithmetic here.
In this problem
F[i] -> i th Fibonacci number. MOD = 1e9 + 7. n < 1e18
F[n] % MOD = ?
F[n] = F[n-1] + F[n-2]
if you calculate this with loop you get TL
that`s way you can optimize this solution
now you calculate F[n] with recursion
F[2*n] = - F[n] * F[n] + 2 * F[n] * F[n+1]
F[2*n+1] = F[n] * F[n] + F[n+1] * F[n+1]
here is my solution
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll MOD = 1e9+7;
void fib(ll n ,ll &a , ll &b){
if(n == 0){
a = 0;
b = 1;
return;
}
ll x, y;
if(n%2==1){
fib(n-1 ,x,y);
a = y;
b = (x+y)%MOD;
return;
}
fib(n/2 , x , y);
a = (x*(2*y +MOD -x)%MOD)%MOD;
b = ((x*x)%MOD+(y*y)%MOD)%MOD;
return;
}
int main(){
ll N , a, b;
cin >> N;
fib(N , a, b);
cout << a;
}
I think the problem with this code is that you are creating an array seq[n] of size n, which can lead to a SEGFAULT on Linux and STATUS_STACK_OVERFLOW (0xc00000fd) on Windows for large numbers, which refers to stack exhaustion.
Below I give an improved version of your algorithm, which uses a fixed memory size, and for modulo addition, I use the sum_by_modulo function, for avoiding overflow in (a + b) % m operation, the principle of which is described here.
#pragma GCC optimize("Ofast")
#include <iostream>
typedef unsigned long long int ullong;
ullong sum_by_modulo(ullong a, ullong b, ullong m){
ullong sum;
a %= m;
b %= m;
ullong c = m - a;
if (b==c)
sum = 0;
if (b<c)
sum = a + b;
if (b > c)
sum = b-c;
return sum;
}
int main()
{
ullong n;
ullong t1 = 0, t2 = 1, nextTerm = 0;
ullong modulo = 1000000000 + 7;
std::cout << "Enter the number of term: ";
std::cin >> n;
for (ullong i = 1; i <= n; ++i)
{
if(i == 1)
continue;
if(i == 2)
continue;
nextTerm = sum_by_modulo(t1, t2, modulo);
t1 = t2;
t2 = nextTerm;
}
std::cout << nextTerm << " ";
return 0;
}
I'm trying to compute math combinations. The formula I'm using is N! / K! (N-K)!.
I am able to get the right answer (10) with N=5, K=2, and 120 from N=10, K=3.
BUT when I tried to test with bigger number like N=50, K=5. The integer division by zero error popped out.
I tried to define finalAns with long int but it does not work as well. Any ideas?
int N;
int init;
int K;
int factN = 1;
int factK = 1;
double finalAns;
cout << "Input of N = ";
cin >> N;
cout << "Input of K = ";
cin >> K;
int subs = N - K;
int factsubs = 1;
for (init = 1; init <= N; init++)
{
factN = factN * init;
}
for (init = 1; init <= K; init++)
{
factK = factK * init;
}
cout << "K is " << factK << endl;
for (init = 1; init <= subs; init++)
{
factsubs = factsubs * init;
}
finalAns = factN / (factK * factsubs);
cout << N << "C" << K << " is " << finalAns << endl;
You need to change the multiply-at-one-go approach.
Don't calculate N! at one go.
Use the fact that division of any two positive integers reduces the end result, so favor division to have the lower intermediate values.
Expand the expression of N!/(N-K)! * K! to accommodate as much of division operation in intermediate steps as possible to lessen the chance of overflow.
Do not go for calculation of N! or (N-K)! or K! separately, you are more likely to face the overflow problem. Instead use the fact that eventually you need to divide the big numbers, why not do it before it becomes BIG!
More hints:
N!/(N-K)! = multiply i[N..N-K+1] one by one //not i[N..1]
and, check if any factor(f) of value j from [2..K] perfectly divides the intermediate-product-value(p), if yes, do the division : p = p/f and j = j/f.
10! is very big: 3.628.800 - if this one is big, just imagine 50!
Depending on what compiler you are using, you might handle preety good 15! using long long. However that is not big enough - so you need to do something else... You can make an algorithm for multiplication that returns a character array - there is no way to return a long int or something else like that.
I am having the hardest time figuring out what is wrong here:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double fact(double);
double sinTaylor(double);
double cosTaylor(double);
int main()
{
double number, sineOfnumber, cosineOfnumber;
cout << "Enter a number, then I will calculate the sine and cosine of this number" << endl;
cin >> number;
sineOfnumber = sinTaylor(number);
cosineOfnumber = cosTaylor(number);
cout << fixed << endl;
cout << cosineOfnumber << endl;
cout << sineOfnumber << endl;
return 0;
}
double fact(double n)
{
double product = 1;
while(n > 1)
product *= n--;
return product;
}
double sinTaylor(double x)
{
double currentIteration, sumSine;
for(double n = 0; n < 5; n++)
{
currentIteration = pow(-1, n)*pow(x, 2*n+1) / fact(2*n+1);
sumSine += currentIteration;
}
return sumSine;
}
double cosTaylor(double y)
{
double currentIteration, sumCosine;
for(double n = 0; n < 5; n++)
{
double currentIteration = pow(-1, n)*pow(y, 2*n) / fact(2*n);
sumCosine += currentIteration;
}
return sumCosine;
}
Ok, so here's my code. I'm pretty content with it. Except for one thing:
sineOfnumber and cosOfnumber, after the calling of sinTaylor and cosTaylor, will add each other in the following cout line that will print each other.
In other words, if number is equal to lets say, .7853, 1.14 will be printed in the line that is intended to print cosineOfnumber, and sineOfnumber will print the result normally.
Can anyone help me identify why this is? Thank you so much!
Are you ever initializing the variables sumSine and sumCosine in your functions? They're not guaranteed to start at zero, so when you call += inside your loop you could be adding computed values to garbage.
Try initializing those two variables to zero and see what happens, as other than that the code seems okay.
The series for the sine is (sorry for the LaTeX):
sin(x) = \sum_{n \ge 0} \frac{x^{2 n + 1}}{(2 n + 1)!}
If you look, given term t_{2 n + 1} you can compute term t_{2 n + 3} as
t_{2 n + 3} = t_{2 n + 1} * \frac{x^2}{(2 n + 2)(2 n + 3)}
So, given a term you can compute the next one easily. If you look at the series for the cosine, it is similar. The resulting program is more efficient (no recomputing factorials) and might be more precise. When adding up floating point numbers, it is more precise to add them from smallest to largest, but I doubt that will make a difference here.
I did something like this
long double n;
cin >> n;
n = n * 10000;
long long int temp = (long long) n;
now when i try to print temp, then a problem occours in some test cases like 2.36
for 2.36 the value of temp should be 23600 but the value of temp comes out to be 23599
Pls someone help me out with this already got 4 wrong ans for this.. small problem
for simplification ..
my code goes like this
int main()
{
int t;
for(scanf("%d", &t); t-- ;) {
float n;
scanf("%f", &n);
n *= 10000;
long int as = (long int) n;
cout << "\nas : " << as << " n : " << n << endl;
long a, b;
a = as;
b = 10000;
while(a%b != 0) {
long temp = a % b;
a = b;
b = temp;
}
long factor = b;
cout << (10000/factor) << endl;
}
return 0;
}
the aim of this program was something that .. i was given a number that can have at max 4 places after the decimal. that was the average score scored by a batsman so we had to find the minimum number of matches he should play to get that score
This is because of the way floating-points are represented internally. You should round them off before performing truncation.
Doing a floor(n+0.5) or a ceil(x-0.5) would round the number correctly.
EDIT:
As your truncation step is a floor(..) operation in itself, you should just do n = n * 10000 + 0.5 as #Mooing Duck stated.
(Example)