Fibonacci Number modulo m - c++

Task: Given two integers n and m, output Fn mod m (they is, the remainder of Fn when divided by m).
My Code:
#include <iostream>
#include <vector>
using namespace std;
long long get_pisano_period(long long m)
{
long long a = 0, b = 1, c;
for (int i = 0; i < m * m; i++)
{
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
return i + 1;
}
}
long long calc_fib(long long n)
{
vector<long long> nums(n + 1);
nums.at(0) = 0;
nums.at(1) = 1;
for (long long i = 2; i < nums.size(); i++)
{
nums.at(i) = nums.at(i - 1) + nums.at(i - 2);
}
return nums.at(n);
}
long long solve(long long n, long long m)
{
long long r = n % get_pisano_period(m);
return (calc_fib(r) % m);
}
int main()
{
long long n, m;
cin >> n >> m;
cout << solve(n, m) << endl;
return 0;
}
My code is working for some cases(small numbers). Can anyone suggest to me, What changes should I make to run this?
Input:
239
1000
Output:
-191
You can see I am supposed to get 161 as output.

I tried what #idclev463035818 said and this seems to work.
Try it,
# include <iostream>
# include <vector>
using namespace std;
long long get_pisano_period(long long m)
{
long long a = 0, b = 1, c;
for (long long i = 0; i < m * m; i++)
{
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
return i + 1;
}
}
long long calc_fib(long long n, long long m)
{
vector<long long> nums(n + 1);
nums.at(0) = 0;
nums.at(1) = 1;
long long maximum = get_pisano_period(m);
for (long long i = 2; i < nums.size(); i++)
{
nums.at(i) = (nums.at(i - 1)%m + nums.at(i - 2)%m)%m;
}
return nums.at(n);
}
int main()
{
long long n, m;
cin >> n >> m;
cout << calc_fib(n, m) << endl;
return 0;
}

Related

Prim Algorithm application

everyone, I have a weighted connected undirected graph, I need to find it's minimum spanning tree weight. On input I have numbers n(vertices amount), m(edges amount). And then m edges in format: A(out vert), B(in vert), C(weight). Here is input example:
3 3
1 2 1
2 3 2
3 1 3
I see it as a typical Prim algorithm, so I used it, but some tests are telling me that my code gives a wrong answer. Here it is:
#include <numeric>
#include <iostream>
using namespace std;
long long primAlgo(const int vertices, const vector<vector<long long>> &edges) {
vector<bool> visited(vertices, false);
vector<long long> minimal(vertices, 30001);
minimal[0] = 0;
for (size_t i = 0; i != vertices; ++i) {
int vert = -1;
for (size_t option = 0; option != vertices; ++option) {
if (!visited[option] && (vert == -1 || minimal[option] < minimal[vert]))
vert = option;
}
visited[vert] = true;
for (size_t to = 0; to != vertices; ++to) {
if (edges[vert][to] < minimal[to]) {
minimal[to] = edges[vert][to];
}
}
}
long long sum = 0;
for (size_t i = 0; i != vertices; ++i) {
sum += minimal[i];
}
return sum;
}
int main() {
int n, m;
cin >> n >> m;
int A, B;
long long C;
vector<vector<long long>> l(n, vector<long long> (n, 30001));
for (size_t i = 0; i != m; ++i) {
cin >> A >> B >> C;
l[A - 1][B - 1] = C;
l[B - 1][A - 1] = C;
}
long long ans = primAlgo(n, l);
cout << ans;
}
So I was wondering, if you know, what the problem may be.

Top Down Approach for this dynamic programming problem

Here is the problem-
You are given array B of size n. You have to construct array A such that 1<=A[i]<=B[i] and sum of the absolute difference of consecutive pairs of A is maximized ,that is, summation of abs(A[i]-A[i-1]) is maximised.You have to return this cost.
Example B=[1,2,3] A can be [1,2,1],[1,1,3],[1,2,3] In all these cases cost is 2 which is the maximum.
Constraints n<=10^5 ,1<=B[i]<=100
Here is my approach -
Cost will be maximum when A[i]=1 or A[i]=B[i]
So I created dp[idx][flag][curr] of size [100002][2][102] where it calculates the cost till index idx. flag will be 0 or 1 representing if A[i] should be 1 or B[i] respectively. curr will be the value of A[i] depending upon flag
Here is my code
#include<bits/stdc++.h>
using namespace std;
#define boost ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
typedef long long int ll;
#define mod 1000000007
ll n;
ll dp[100002][2][101];
ll b[100005];
ll solve(ll idx,ll flag,ll curr)
{
if(idx>=n)
return 0;
ll s1=0;
if(dp[idx][flag][curr]!=-1)
return dp[idx][flag][curr];
if(idx==0)
{
int left=solve(idx+1,0,curr);
int right=solve(idx+1,1,curr);
return dp[idx][flag][curr]=max(left,right);
}
else
{
if(flag==0)
{
s1=abs(curr-1);
return dp[idx][flag][curr]=s1+max(solve(idx+1,0,1),solve(idx+1,1,1));
}
else
{
s1=abs(b[idx]-curr);
return dp[idx][flag][curr]=s1+max(solve(idx+1,0,b[idx]),solve(idx+1,1,b[idx]));
}
}
}
int main()
{
boost
ll t;
cin>>t;
while(t--)
{
cin>>n;
memset(dp,-1,sizeof(dp));
ll res=0;
for(int i=0;i<n;i++)
cin>>b[i];
ll s1=solve(0,0,1);//Starting from idx 0 flag 0 and value as 1
ll s2=solve(0,1,b[0]);//Starting from idx 0 flag 1 and value as B[0]
cout<<max(s1,s2)<<"\n";
}
}'
Is there any way to reduce states of dp or any other top down solution because my code fails if values of B[i] are large
You implement a recursive approach. Here, a simple iterative implementation allows to get a time efficiency of O(n) and a space efficiency of O(1)
(not counting the space needed for the input array).
You correctly stated that at index i, we have two choices only, a[i]=1 (flag = 0) or a[i]=b[i] (flag = 1)
The basic idea is that, when studying what choice to make at index i, we only need to know what are the optimum sums ending at index i-1, for flag = 0 (sum0) or flag = 1 (sum1).
We don't need to explicitely calculate the array a[.].
Note: I kept long long int as in your code, but it seems that int is quite enough here.
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define mod 1000000007 // needed ???
long long int sum_diff (const std::vector<long long> &b) {
int n = b.size();
long long int sum0 = 0;
long long int sum1 = 0;
for (int i = 1; i < n; ++i) {
long long int temp = std::max (sum0, sum1 + b[i-1] - 1); // flag = 0: a[i] = 1
sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1])); // flag = 1: a[i] = b[i]
sum0 = temp;
}
return std::max (sum0, sum1);
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
std::cin >> t;
while(t--) {
int n;
std::cin >> n;
std::vector<long long int> b(n);
for(int i = 0;i < n; i++) std::cin >> b[i];
long long int s = sum_diff (b);
std::cout << s << "\n";
}
}
As you insist to have a top-down (recursive) aproach, I have implement both approaches in the following code. But I insist that the iterative solution is better in this case.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
int sum_diff (const std::vector<int> &b) {
int n = b.size();
int sum0 = 0;
int sum1 = 0;
for (int i = 1; i < n; ++i) {
int temp = std::max (sum0, sum1 + b[i-1] - 1); // flag = 0: a[i] = 1
sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1])); // flag = 1: a[i] = b[i]
sum0 = temp;
}
return std::max (sum0, sum1);
}
void sum_diff_recurs (const std::vector<int> &b, int i, int&sum0, int &sum1) {
if (i == 0) {
sum0 = sum1 = 0;
return;
}
sum_diff_recurs (b, i-1, sum0, sum1);
int temp = std::max (sum0, sum1 + b[i-1] - 1); // flag = 0: a[i] = 1
sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1])); // flag = 1: a[i] = b[i]
sum0 = temp;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
std::cin >> t;
while(t--) {
int n, sum0, sum1;
std::cin >> n;
std::vector<int> b(n);
for(int i = 0; i < n; i++) std::cin >> b[i];
int s = sum_diff (b);
std::cout << s << "\n";
sum_diff_recurs (b, n-1, sum0, sum1);
std::cout << std::max(sum0, sum1) << "\n";
}
}
Actually I found the solution using only two states idx and flag
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll n,k;
ll dp[100002][2];
ll b[100005];
ll solve(ll idx,ll flag)
{
if(idx>=n-1)
return 0;
if(dp[idx][flag]!=-1)
return dp[idx][flag];
ll val=(flag==1)?b[idx]:1;
ll left=solve(idx+1,0)+val-1;
ll right=solve(idx+1,1)+abs(val-b[idx+1]);
return (dp[idx][flag]=max(left,right));
}
int main()
{
ll t;
cin>>t;
while(t--)
{
cin>>n;
memset(dp,-1,sizeof(dp));
ll res=0;
for(int i=0;i<n;i++)
cin>>b[i];
ll s1=solve(0,0);
ll s2=solve(0,1);
cout<<max(s1,s2)<<"\n";
}
}

Sum and sum of squares of digits -coprime

For the paragraph L, R
its sum of digits and the sum of its squares (in the decimal) is co-
prime.
Count how many numbers in the paragraph L, R meet the above conditions
I was stuck on the sub21
exceeds time limit when R = 10^8 and Max R = 10^18:
#include<bits/stdc++.h>
using namespace std;
class tinhtong
{
public:
long long getSum(long long n)
{
long long int sum = 0;
while (n != 0)
{
sum = sum + (n % 10);
n = n/10;
}
return sum;
}
};
class binhphuong
{
public:
long long getpow(long long n)
{
long long poww = 0;
while (n != 0)
{
poww = poww + (n % 10)*(n % 10);
n = n/10;
}
return poww;
}
};
int main()
{
tinhtong g;
binhphuong h;
long long TONG=0,k,l,ucln;
long long int m,n;
cin>>n>>m;
for(n;n<=m;n++)
{
ucln=0;
k=g.getSum(n);
l=h.getpow(n);
while(k!=0 && l!=0)
{
if(k>l)
k-=l;
else
l-=k;
}
if(k==0)
ucln=l;
else
ucln=k;
if (ucln==1)
TONG++;
}
cout<<TONG;
return 0;
}
As mentioned in comments, you can calculate the sum and the sum of squares in one loop, avoiding multiple calls of same % operation.
Moreover, to calculate that two numbers are coprime, it is better to use the version of Euclide's algorithm that uses modulo instead of substractions. The code is below.
In this code, I use the fact that the sum of squares is greater or equal the sum.
I also use the fact that if the sum is a multiple of 2, it is also the case for the sum of squares.
If this code is not fast enough, you can try the suggestion in a comment to first convert the number to a string.
Another possibility would be the check if both numbers are multiple of 3 or 5, before calculating the GCD, as GCD calculation can be longer.
#include <iostream>
#include <tuple>
std::pair<long long, long long> getSum_pow(long long n) {
long long int sum = 0;
long long int sumP = 0;
while (n != 0) {
long long r = n%10;
sum += r;
sumP += r*r;
n = n/10;
}
return {sumP, sum};
};
int main() {
long long TONG = 0, a, b;
long long int m, n;
std::cin >> n >> m;
for(; n <= m; n++) {
std::tie (a, b) = getSum_pow(n);
if (b%2 == 0) continue;
while (b != 0) {
a = a%b;
std::swap (a, b);
}
if (a == 1) {
TONG++;
}
}
std::cout << TONG;
return 0;
}

CPP Prime Generator SPOJ Sieve

I did implement Sieve prime generator. The code is pretty fast and consumes less memory. https://www.spoj.com/problems/PRIME1/
But I get "Wrong Answer" when I submit the solution. People online seem to just make the set the max to 32000 and run the solution. I don't exactly get where am I actually wrong? Or Is it just an extra newline (if possible) that makes the solution to be incorrect?
#include <iostream>
#include <unordered_map>
using namespace std;
int main(void) {
unordered_map<long long int, bool> notPrime;
notPrime[0] = true;
notPrime[1] = true;
for (long long int x = 2; x < 100000; x++) {
if (notPrime[x]) continue;
for (long long int u = 2 * x; u < 100000; u += x)
notPrime[u] = true;
}
int n;
cin >> n;
while (n--) {
long long int s, e;
cin >> s >> e;
if (s < 0)
s = 0;
for (long long int i = s; i <= e; i++) {
if (!notPrime[i]) {
cout << i << '\n';
}
}
if (n)
puts("");
}
return 0;
}

How to select all possible combination of elements from a set using recursion

This is a question from hackerrank; I am trying to understand how recursion works.
The task at hand is:
Find the number of ways that a given integer, X, can be expressed
as the sum of the Nth power of unique, natural numbers.
So for example, if X = 100 and N = 2
100 = 10² = 6² + 8² = 1² + 3² + 4² + 5² + 7²
so 100 can be expressed as the square of unique natural numbers in 3
different ways, so our output is 3.
Here is my code,:
#include <cmath>
#include <iostream>
using namespace std;
int numOfSums(int x, int& n, const int k) {
int count = 0, j;
for (int i = (k + 1); (j = (int) pow(i, n)) <= x; i++) {
j = x - j;
if (j == 0)
count++;
else
count += numOfSums(j, n, i);
}
return count;
}
int main() {
int x, n;
cin >> x >> n;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
But when I input x = 100 and n = 2, it's outputting 2, not 3. What's wrong with the code?
Link to the question: https://www.hackerrank.com/challenges/the-power-sum
Your example code returns 3 when I run it using this main():
#include <iostream>
int main() {
int x = 100, n = 2;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
The problem is likely that you're using double std::pow(double, int), but you're not rounding the result to nearest integer ((int) casts round down). You should add ½ before truncating:
j = static_cast<int>(pow(i, n) + 0.5)
I've used the more-C++ style of cast, which I find clearer.
It would be more efficient to implement your own equivalent of std::pow() that operates on integers. That can be recursive, too, if you want:
unsigned long pow(unsigned long x, unsigned long n)
{
return n ? x * pow(x, n-1) : 1;
}
An iterative version is more efficient (or a tail-recursive version and suitable optimizing compiler).
Reduced version, with my changes:
template<typename T>
T powi(T x, T n)
{
T r{1};
for (; n; n /= 2) {
r *= n%2 ? x : 1;
x *= x;
}
return r;
}
template<typename T>
T numOfSums(T x, T n, T i = {})
{
T count{}, j;
for (++i; (j = powi(i, n)) <= x; ++i)
count += j == x ? 1 : numOfSums(x-j, n, i);
return count;
}
#include <iostream>
int main()
{
unsigned long int x = 100, n = 2;
std::cout << numOfSums(x, n) << std::endl;
return 0;
}