Sum and sum of squares of digits -coprime - c++

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;
}

Related

Fibonacci Number modulo m

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;
}

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;
}

Fenwick Tree HackerEarth

I have the following implementation of a Fenwick tree to solve the following Question on HackeEarth.
#include <iostream>
#define MAX 1000000007
using namespace std;
long long int dp[500006];
long long int GCD[500006];
// Function to Calculate GCD
int gcd(int u, int v){
int shl = 0;
while ( u && v && u!=v ) {
bool eu = !(u & 1);
bool ev = !(v & 1);
if ( eu && ev ) {
++shl;
u >>= 1;
v >>= 1;
}
else if ( eu && !ev ) u >>= 1;
else if ( !eu && ev ) v >>= 1;
else if ( u>=v ) u = (u-v)>>1;
else {
int tmp = u;
u = (v-u)>>1;
v = tmp;
}
}
return !u? v<<shl : u<<shl;
}
//Function to calculate Cumulative GCD
long long int cumulativeGCD(int x){
long long int sum = 0;
if(!dp[x]){
for(int i=1;i<=x;i++){
sum += gcd(i,x);
}
dp[x] = sum;
return sum;
}
else return dp[x];
}
// Retrieve the SUM function
long long int getSum(long long int BITree[], int index)
{
long long int sum = 0; // Iniialize result
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse ancestors of BITree[index]
while (index>0)
{
// Add current element of BITree to sum
sum += BITree[index];
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Update BIT function
void updateBIT(long long int BITree[], int n, int index, long long int val)
{
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n)
{
// Add 'val' to current node of BI Tree
if(BITree[index]>MAX)
BITree[index] = (BITree[index] + val)%MAX;
else BITree[index] += val;
// Update index to that of parent in update View
index += index & (-index);
}
}
// Construct BIT function
long long int *constructBIT(int arr[], int size){
long long int *BITree = new long long int[size+1]();
for (int i=0; i<size; i++)
updateBIT(BITree, size, i, GCD[i]);
return BITree;
}
int main()
{
int size,queries,index,value,start,end;
char type;
scanf("%d",&size);
int *arr= new int[size];
for(int i=0;i<size;i++){
scanf("%d",&arr[i]);
GCD[i] = cumulativeGCD(arr[i]);
}
long long int *BIT = constructBIT(arr,size);
scanf("%d",&queries);
while(queries--){
cin>>type;
if(type=='C'){
scanf("%d %d",&start,&end);
printf("%lld\n",getSum(BIT,end-1) - getSum(BIT,start-2));
}
if(type=='U'){
scanf("%d %d",&index,&value);
long long int diff = cumulativeGCD(value)-cumulativeGCD(arr[index-1]);
updateBIT(BIT,size,index-1,diff);
}
}
return 0;
}
My solution is exceeding the time limit for 7 out of the 10 tests cases. I am not able to optimize this code further. How could I possibly optimize this so that it may run under 1 sec for each of the test cases. Thank you very much !
Provide the link that points to the problem that you're solving, so that we can better understand the scenario and suggest you. However, the gcd() function can be modified as:
typedef long long ll;
ll gcd(ll a,ll b){
if(!b)
return a;
else return gcd(b,a%b);
}
remove
if(BITree[index]>MAX)
BITree[index] = (BITree[index] + val)%MAX;
else BITree[index] += val;
and replace with
BITree[index] = (BITree[index] + val) % MAX;
as you're not checking BITree[index] + val > MAX

computes the number of ways to partition n into the sum of positive integers c++

I need to write function as part of assignment..
I need to compute the number of ways to partition n into the sum of positive integers and I can't use for while or goto
/*
* REQUIRES: n > 0
* EFFECTS: computes the number of ways to partition n into the sum of
* positive integers
* MUST be tree recursive
* Hint: Use a helper function that computes the number of ways to
* partition n using a bounded subset of integers. Then use logic
* similar to count_change() from lecture to divide partitions into
* those that use a specific item and those that do not.
*/
int num_partitions(int n);
I figured a way to print them but unable to count it and my function also needed for loop. Here's function
void print(int n, int * a) {
int i ;
for (i = 0; i <= n; i++) {
printf("%d", a[i]);
}
printf("\n");
}
int integerPartition(int n, int * a, int level,int c){
int first;
int i;
if (n < 1)
{
return c;
}
a[level] = n;
print(level, a);
c++;
first = (level == 0) ? 1 : a[level-1];
for(i = first; i <= n / 2; i++){
a[level] = i;
integerPartition(n - i, a, level + 1,c);
}
}
int num_partitions(int n){
int * a = (int * ) malloc(sizeof(int) * n);
return integerPartition (n, a, 0,0);
}
please help...
here is the count change function
int count_change(int amount, const int coins[], int num_coins) {
if (amount == 0) {
return 1;
} else if​ (amount < 0 || num_coins < 1) {
return 0;
} else {
return
count_change(amount - coins[num_coins - 1], coins, num_coins) +
count_change(amount, coins, num_coins - 1);
}
}
You can do it like this:
#include <conio.h>
#include <iostream>
using namespace std;
int integerPartition(int n, int k);
int main()
{
int n;
cin>>n;
int k =n;
cout<<integerPartition(n,k);
getchar();
return 0;
}
int integerPartition(int n, int k)
{
if(k==0)
return 0;
if(n ==0)
return 1;
if(n<0)
return 0;
return integerPartition(n,k-1) + integerPartition(n-k,k);
}
Inspired from: http://www.programminglogic.com/integer-partition-algorithm/
or you can also use: recurrence formula for partition functions, given on
https://en.wikipedia.org/wiki/Partition_(number_theory)

C++ Fraction class does not work on negatives

I am trying to create a fraction class that can do operations on fractions just like the way we did it by hand in elementary school. It works fine with positive numbers but I have tried implementing it with negative numbers and I get breakpoint error. It would be great if someone can tell me what is wrong with it.
#include <iostream>
#include <cmath>
using namespace std;
class fraction
{
private:
long int n;
long int d;
long int gcd();
public:
fraction(long int, long int);
long int num(); //returns num
long int denom(); //returns denom
void print(); //print fraction
void reduce(); //reduce fraction to lowest terms
friend double convert(fraction); //convert function to double
friend fraction operator+ (fraction, fraction);//add two fractions, answer in reduced form
friend fraction operator- (fraction, fraction);//subtract two fractions, reduced
};
long int fraction::gcd()
{
long int divisor = 0;
for (long int i = 1; (i <= n && i <= d) ; i++)
{
if ((n % i == 0) && (d % i == 0))
{
divisor=i;
}
}
return divisor;
}
fraction::fraction(long int x, long int y) //constructor
{
n=x;
d=y;
if ((x <= 0) && (y <= 0))
{
n = -x;
d = -y;
}
}
void fraction::reduce() //change value of n and d
{
long int num = n/gcd();
long int denom = d/gcd();
n = num;
d = denom;
}
long int fraction::num()
{
return n;
}
long int fraction::denom()
{
return d;
}
void fraction::print()
{
cout << n << "/" << d;
}
fraction operator- (fraction x, fraction y)
{
x.reduce();
y.reduce();
fraction temp;
temp.n = (x.n)*(y.d) - y.n*(x.d);
temp.d = (x.d)*(y.d);
temp.reduce();
return temp;
}
int main()
{
fraction f(-5,100), g(-1,-2);
(f-g).print; //returns error!
return 0;
}
The error is caused by the fact that print() is a non-const member function.
When you use:
(f-g).print();
The function is called an a temporary object, which is good for calling const member functions, not non-const member functions.
You can resolve this problem by:
Changing print() to a const member function.
By assigning f-g to an object and calling print on that object.
fraction res = f-g;
res.print();
I would recommend using the first method.
Update
You have a problem in gcd when either n or d is negative. Change it to:
long int fraction::gcd()
{
long int divisor = 1;
// Deal with only positive numbers when computing the gcd.
long int tempN = n < 0 ? -n : n;
long int tempD = d < 0 ? -d : d;
for (long int i = 1; (i <= tempN && i <= tempD) ; i++)
{
if ((tempN % i == 0) && (tempD % i == 0))
{
divisor=i;
}
}
return divisor;
}