Numbers that have two or more prime factors - primes

def fun(n) :
ans = 0
for i in range(1,n) :
for j in range(i+1,n+1) :
ans += gcd(i,j)
This is the actual function to be calculated when n is given. The upper bound for n will be 1e6 and the time limit will be 2 seconds. Directly using the above function will clearly exceed the Time Limit. So, I've come up with a following solution. It works for small cases, but failing to pass when N>=100.
Here is the c++ code :
# include <cstdio>
# include <bits/stdc++.h>
# include <cstring>
# include <cstdlib>
# include <cctype>
# include <string>
# include <cfloat>
# include <cmath>
# include <iostream>
# include <fstream>
# include <cassert>
# include <iterator>
# include <vector>
# include <queue>
# include <map>
# include <algorithm>
# include <set>
# include <sstream>
# include <stack>
# include <cassert>
# define MEM(a,b,s) memset(a,(b),s)
# define MAX(a,b) ((a) > (b) ? (a) : (b))
# define MIN(a,b) ((a) < (b) ? (a) : (b))
# define MP make_pair
# define pb push_back
# define inf 1000000000
# define MOD 1000000007
# define SZ 1000001
# define lli long long int
# define li long int
# define repeat(i,a) for(lli i=1;i<a;i++)
# define repeat_untill(a) while (a)
# define repeat2(i,j,k) for (j=i+1;j<=k;j++)
# define ch char
# define gi(a) readFast<int>(&a)
# define gl(a) readFast<li>(&a)
# define gll(a) readFast<lli>(&a)
using namespace std;
template <class fast_io>
inline fast_io readFast(fast_io *a)
{
char c=0;
int sign=0;
while(c<33 && c!='-')
c=getchar_unlocked();
*a=0;
if (c=='-')
{
sign=1;
c=getchar_unlocked();
}
while(c>33)
{
*a=*a*10+(c-48);
c=getchar_unlocked();
}
if (sign==1)
return -*a;
else
return *a;
}
int prime[100001];
void sieve()
{
MEM(prime,0,100001);
for (int i=2;i<100001;i++)
{
if (!prime[i])
{
lli j=2;
while (i*j < 100001)
{
prime[i*j] = 1;
j += 1;
}
}
}
}
lli gcd(lli a,lli b)
{
return (b==0?a:gcd(b,a%b));
}
int main(void)
{
lli n;
sieve();
gll(n);
repeat_untill(n)
{
lli i , j , ans =0;
repeat(i,n)
{
lli divs,coprimes=0;
if (n%i == 0)
{
divs = (n/i)-1;
coprimes = (n-i)-divs;
ans += ((divs*i)+coprimes);
}
else
{
lli k = (int)(pow(i,0.5)),m=2,totdiv=0;
if (k*k < i)
k += 1;
while (m<=k)
{
if (!prime[m])
{
divs = (n-i)/m;
totdiv += divs;
ans += ((divs*m));
}
m += 1;
}
ans += (n-i-totdiv);
}
}
cout<<ans<<endl;
gll(n);
}
return (0);
}
The problem here is if there will be n-i such that it has two prime factors, then this algo will fail as for a value i each j greater than i and lesser than n will only be taken into account for gcd calculation once. For example if n-i will be 25 then prime factors that it has will be 2,3,5. Here 15 will be considered twice at 3 and 5. Kindly help how can i eliminate the 15 after performing the action with 3.
Or is there any other approach to calculate the function fun(n) faster below O(n^2)?
Thanks in advance!

Related

Recursively nested Radicals C++

I'm trying to write a function for the first n terms of sqrt(1+sqrt(2+sqrt(3+...))) in C++. The constraint is that the function must be recursive and take n (the depth of the nest) as the only parameter. I do not need to return the expression itself, just what it evaluates to. For example:
n=1 -> sqrt(1) # which evaluates to 1
n=2 -> sqrt(1+sqrt(2)) # which evaluates to 1.55377
n=3 -> sqrt(1+sqrt(2+sqrt(3))) # which evaluates to 1.7122
I've tried:
float nestedRadical(float n){
if (n==1){
return sqrt(1);
}else{
return sqrt(n + nestedRadical(n-1));
}
}
This code causes 1 to be the most deeply nested radical, when it should be the highest. How should should I approach this problem?
Examine and analyze nested radicals carefully. Write on paper, even if needed. then you will understand better.
Try this:
#include <iostream>
#include <math.h>
using namespace std;
double recursivelNestedRadicals(int n, int i) {
double res = 0;
if(i-1 == n)
return res;
else
res = sqrt(i + recursivelNestedRadicals(n, i+1));
}
int main() {
int number;
cout<<"Enter number: ";
cin>>number;
cout<<recursivelNestedRadicals(number, 1);
}

C ++ using multiple cores breakes output , code for a math problem

So, for start im just starting to learn c++, and i had to resolve this problem: Find the numbers with the propriety : 5 * 5 = 25 , 25 * 25 =625(25squared), 6*6 =36(6squared) ( 25 is the ending of 625, 5 is the the ending of 25 ). So i've got my code to find all the numbers lower than 30k , but then i wanted to push it to it's limit ,so up to lluint_max, but it was really slow, i saw that my 12 core cpu is not utilised so i thought i'd add more cpu cores. I wanted to find the easiest fix and i found openmp, read a little and foun that if i add omp for it should divide the load to multiple cores, but the console doesn't display my numbers anymore.(PS i enabled omp in vs)
Here's my code:
#include <iostream>
#include <cmath>
#include <climits>
#include <omp.h>
using namespace std;
int main()
{
long long int x, i, nc = 0, z = 1, p;
#pragma omp for
for (x = 1; x <= ULLONG_MAX; x++)
{
//numarul de cifre a lui x
while (x / z != 0)
{
z = z * 10;
nc = nc + 1;
}
//patratul
p = x * x;
i = pow(10, nc);
if (p % i == x)
cout << x << endl;
}
}
And heres my output:
C:\Users\Mihai Cazac\source\repos\ConsoleAPP2\Debug\ConsoleAPP2.exe (process 8736) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .
Expected output:
1
5
6
25
76
376
625
9376
90625
109376
890625
2890625
7109376
12890625
//and so on
Thanks in advance!!
So i've resolved it , special thanks to Raymond Chen for his comment and the blog he directed me to, http://supercomputingblog.com/openmp/tutorial-parallel-for-loops-with-openmp/
This site explained it really well.
I declared the variables as late as possible, also changhed to LLInt_Max as openmp doesnt want to work with unsigned only ,idk why
Also schedule dynamic seems to divide the workload,but i may be wrong.
My final code:
#include <iostream>
#include <cmath>
#include <climits>
#include <omp.h>
using namespace std;
int main()
{
#pragma omp parallel for schedule(dynamic)
for (long long int x = 1; x < LLONG_MAX; x++)
{
long long int t = x;
int d = 0;
while (t > 0)
{
t = t / 10;
d++;
}
//patratul
long long int p = x * x;
long long int i = pow(10, d );
if (p % i == x)
cout << x << endl;
}
}

why does my code get segment fault on SPOJ for Sum of Digits problem? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
When I submitted the solution of a dp problem on spoj for this problem I always get a segment fault. But my solution works on other platforms like visual studio and Ideone.
I do not know why I am getting this error, Can you help?
My code:
#include <iostream>
#include <cmath>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iomanip>
#include <assert.h>
#include <vector>
#include <cstring>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <set>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <climits>
#include <cctype>
#include <bitset>
#include <numeric>
#include <array>
#include <tuple>
#include <stdexcept>
#include <utility>
#include <functional>
#include <locale>
#define mp make_pair
#define pb push_back
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define sz size()
#define len length()
#define vi vector<int>
#define vll vector<ll>
#define vs vector<string>
#define all(v) ((v).begin()), ((v).end())
#define mms(Arr, Value) memset(Arr, Value, sizeof(Arr))
#define printl(ans) cout << ans << endl
#define vpii vector<pair<int, int> >
#define vpll vector<pair<ll, ll> >
#define pll pair<ll, ll>
#define re return
#define fri(x,n) for(int i = x ; i < n ; ++i)
#define frj(x,n) for(int j = x ; j < n ; ++j)
typedef long long int ll;
const int oo = INT_MAX;
const ll OO = 1e18;
using namespace std;
ll GCD(ll a, ll b) { return((!b) ? a : GCD(b, a % b)); }
ll LCM(ll a, ll b) { return a / (GCD(a, b)) * b; }
bool isPrime(ll n) {
if (n == 2)re 1;
if (n < 2 || n % 2 == 0)re 0;
for (ll i = 3; i * i <= n; i += 2)
if (n % i == 0)re 0;
re 1;
}
// take it as string
string a, b;
int ar[11];
ll dp[11][100][2]; // if max input is 1e9, so max pos is 10 and max sum of a one number is 9*9.. did not put a dimension for n as it is constant for all states
ll fun(int pos, ll sum, int flag, int n) {
if (pos > n) re dp[pos][sum][flag] = sum;
if (dp[pos][sum][flag] != -1) re dp[pos][sum][flag];
// if flag is 0 then this state is limited by ar[pos] value.
int limit = 9;
if (flag == 0) limit = ar[pos];
// determine next state: put next flag not limited (1) when curr flag is not limited (1) OR i is still under (smaller than) limit
// put next flag limited (0) when curr flag is limited AND i equals the limit .. you can NOT put OR as : the flag of curr state may be limited but the next state
// would be limited only if i==limit, as if i<limit the next state is always free whether flag is 1 or 0.
// if i==limit, the next state would only be limited if flag is 0. as if curr flag was free so limit of curr state was 9 and now i is 9, the next state can not be limited because flag is 1 even if i==limit.. so you must put them both !flag , i==limit and you must put AND
ll res = 0;
fri(0, limit + 1) {
if (!flag && i == limit)
res += fun(pos + 1, sum + i, 0, n); // limited
else
res += fun(pos + 1, sum + i, 1, n); // free
}
re dp[pos][sum][flag] = res;
}
int NumDigitSum(string s) {
// takes the num as string and return the sum of its digits
int sum = 0;
fri(0, s.sz) {
sum += s[i] - '0';
}
re sum;
}
int main() {
IO;
cin >> a >> b;
while (a != "-1") {
mms(dp, -1);
// ar is one indexed
fri(1, a.sz + 1) {
ar[i] = a[i - 1] - '0'; // convert to int
}
ll aans = fun(1, 0, 0, a.sz);
mms(dp, -1);
// ar is one indexed
fri(1, b.sz + 1) {
ar[i] = b[i - 1] - '0'; // convert to int
}
ll bans = fun(1, 0, 0, b.sz);
cout << bans - aans + NumDigitSum(a) << endl;
cin >> a >> b;
}
return 0;
}
Well, this kind of spoonfeeding is pretty discouraged, but here I go:
#include <iostream>
#include <string>
//number of headers = 3
//no use of using namespace std;
int main() {
int n = 100;
long sum = 0;
for (int i = 1; i <= n; i++) {
std::string num_as_string = std::to_string(i);
for(const auto& digit_as_char : num_as_string) {
sum = sum + digit_as_char - '0';
}
}
std::cout << sum;
return 0;
}
Notice some things in the code:
It is short and concise
It uses the standard string library to separate digits which is way better than a custom logic
It is very much readable and does not get on anyone's nerves

Perfect squares in a given range: abnormal execution of loops

Program number 1:
In a given range a and b where a<=b, I want to find whether a number is a perfect quare, if yes then print its root. Therefore, I wrote the following code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
float squaredroot(int n) {
float low = 0.0, mid;
float high = (float)n+1;
while ((high-low) > 0.00001) {
mid = (low+high) / 2;
if (mid*mid < n) {
low = mid;
}
else {
high = mid;
}
}
return low;
}
int main() {
int a,b,i=0; cin>>a>>b;
float roo=0.0;
for(i=a;i<=b;i++){
roo=squaredroot(i);
if(floor(roo)==roo){
cout<<roo<<endl;
}
}
return 0;
}
For the given input 1 5 the output should be 2. But, the above program is not printing any value.
Nevertheless, when I tried running another program using the same base concept as Program number 1, that's mentioned above, It was executed perfectly.
The task for the following program is to check whether the input is a perfect square or not. If yes, then print the root of the number, else print "Not a perfect square!". Here is the code for the Program number 2:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
float squaredroot(int n) {
float low = 0.0, mid;
float high = (float)n+1;
while ((high-low) > 0.00001) {
mid = (low+high) / 2;
if (mid*mid < n) {
low = mid;
}
else {
high = mid;
}
}
return low;
}
int main() {
int a; cin>>a;
float roo=0.0;
roo=squaredroot(a);
if(floor(roo)==roo){
cout<<roo<<endl;
}
else{
cout<<"Not a perfect square!"<<endl;
}
return 0;
}
I am unable to find the mistake in the first program. Please help.
Instead of messing about with the square root function, consider this:
Consecutive squares are separated by succeeding odd numbers.
It's pretty darned fast to add some integers. Also you are skipping more and more numbers each time.
Square root takes you to floats. This keeps the problem in integers, where it belongs.
So, to solve your problem elegantly, just do this:
#include <iostream>
using std::cout;
void print_perfect_square( int start, int end ) {
int x = 0, nthOdd = 1;
while ( x <= end ) {
if ( x >= start ) {
cout << x << " is a square and its root is "
<< nthOdd - 1 << '\n';
}
x += 2*nthOdd - 1;
++nthOdd;
}
}
int main() {
// it should find 9 and 16
print_perfect_square(6,17);
cout << '\n';
// it sholuld skip negatives
print_perfect_square(-10,5);
cout << '\n';
// it should print 25,36...
print_perfect_square(20,100);
return 0;
}
As Gyro Gearloose said, the problem is that squaredroot(4) returns 1.99999809, so floor(roo)!=roo. One way to fix this is to change the condition (floor(roo)==roo) to (fabs(roo - floor(roo+0.5)) < 0.00001). Notice that I'm using the same 0.00001 from the function squaredroot.

Increase number of columns filled in as row number increases

I am writing a program to fill in a matrix (I use the dlib library but not relevant to the question. In the following my goal is for rows 1-19 (row indices 0-18) for one additional column to fill in with my formula. For example row 1 has the first column filled in, row 2 has the first two columns filled in. The first column for every row is preset to my initial value as required. What can I do to the nested for loops indicated by comment my lmm() function to get my desired output?
#include <random>
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <vector>
#include <cmath>
#include <limits>
#include <cstdlib>
#include <chrono>
#include <iterator>
#include <algorithm>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/kurtosis.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/accumulators/statistics/skewness.hpp>
#include <dlib/optimization.h>
#include <dlib/matrix.h>
#include "mleFunctor.h"
#include "mleDerFunctor.h"
using namespace boost::accumulators;
using namespace dlib;
//Generate Gaussian via Box-Muller from Mark Joshi's C++ Design Patterns and Derivatives Pricing
double GetOneGaussianByBoxMuller()
{
double result;
double x;
double y;
double sizeSquared;
do
{
x = 2.0*std::rand() / static_cast<double>(RAND_MAX) - 1;
y = 2.0*std::rand() / static_cast<double>(RAND_MAX) - 1;
sizeSquared = x*x + y*y;
} while (sizeSquared >= 1.0);
result = x*sqrt(-2 * log(sizeSquared) / sizeSquared);
return result;
}
double libSum(matrix<double,20,20> v, matrix<double, 20, 20> lib, int r,int c , double d, int index,std::vector<double> W)
{
double sum = 0.0;
for (auto k = index + 1; k < lib.nr()-1; ++k)
{
sum += ((d*v(k,c-1)*lib(k,c-1))/(1+d*lib(k,c-1)))*v(k,c-1) * lib(r, c-1)*(W[c] - W[c-1]);
}
return sum;
}
void lmm()
{
double dt = .25;
std::vector<double> W(20);
std::vector<double> T;
matrix<double, 20, 20> L;
W[0] = 0;
for (auto c = 1; c < W.size(); ++c)
{
W[c] = W[c - 1] + sqrt(dt)*GetOneGaussianByBoxMuller();
}
for (auto i = 0; i < 20; ++i)
{
T.push_back(i*.25);
}
set_all_elements(L, 0);
set_colm(L, 0) = .003641; //3M Libor Rate on November 16,2015
matrix<double,20,20> vol;
set_all_elements(vol,.15);
//Loop that should fill in one more column each (ie 0 indexed row has one column filled in,
//row index 1 should have 2 columns filled in etc
for (auto c = 1; c < L.nc(); ++c)
{
for (auto r = 1; r < c; ++r)
{
L(r, c) = L(r, c-1) + libSum(vol, L,r,c, .25, c,W) + vol(r,c-1) * L(r, c-1 )*(W[c] - W[c-1]);
}
}
std::ofstream outfile("LMMFlatVol.csv");
outfile << L << std :: endl;
}
int main()
{
lmm();
return 0;
}
As of right now my output is just the preset first columns with the rest of the matrix zeroes as I initialized.
Your primary problem seems to be your loop condition. Note that the inner for loop should start at the first active row. For example, in the third column (c==2) the first time you calculate a value is row three (r==2). After that all rows until the bottom of the matrix have a calculated value.
Your previous logic did not even calculate any value for the second column (c==1) because r was set to 1 and (r < c) evaluated to false!
for (auto c = 1; c < L.nc(); ++c)
{
for (auto r = c; r < L.nc(); ++r)
{
L(r, c) = L(r, c-1) + libSum(vol, L,r,c, .25, c,W) + vol(r,c-1) * L(r, c-1 )*(W[c] - W[c-1]);
}
}