Project Euler #1 test extension - c++

The simple solution to problem 1 is
static unsigned int solutionInefficient(unsigned int n){
unsigned int sum = 0;
for (unsigned int i = 0; i < n; i++){
if (i % 3 == 0 || i % 5 == 0) {
sum += i;
}
}
return sum;
}
I decided to try a different test case with n = 2147483647 and the final result was computed in 12 seconds. So, I came up with another solution that gave me the same answer and took 2 seconds:
static unsigned int solutionEfficient(unsigned int n){
unsigned int sum = 0;
unsigned int sum3 = 0;
unsigned int sum5 = 0;
unsigned int sum15 = 0;
for (unsigned int i = 3; i < n; i += 3){
sum3 += i;
}
for (unsigned int i = 5; i < n; i += 5){
sum5 += i;
}
for (unsigned int i = 15; i < n; i += 15){
sum15 += i;
}
return sum3 + sum5 - sum15;
}
My last attempt at making a faster implementation involved some google searches and using the arithmetic summation formula and the final piece of code looked like this:
static unsigned int solutionSuperEfficient(unsigned int n){
n = n - 1;
unsigned int t3 = n / (unsigned int)3,
t5 = n / (unsigned int)5,
t15 = n / (unsigned int)15;
unsigned int res_3 = 3 * (t3 * (t3 + 1)) *0.5;
unsigned int res_5 = 5 * (t5 * (t5 + 1)) *0.5;
unsigned int res_15 = 15 * (t15 * (t15 + 1)) *0.5;
return res_3 + res_5 - res_15;
}
however this did not provide the correct answer for this test case. It did provide the correct answer for n = 1000. I am not sure why it failed for my test case, any ideas?

You have two problems in your super efficient solution:
You are using floating point number 0.5 instead of dividing by 2. This will cause rounding errors. Note that it is guaranteed that x * (x + 1) is even so you can safely divide by two.
Integer overflow. The calculation t3 * (t3 + 1) and the similar products will overflow unsigned int. To avoid this, use unsigned long long instead.
Here is the corrected code:
static unsigned int solutionSuperEfficient(unsigned int n){
n = n - 1;
unsigned long long t3 = n / 3,
t5 = n / 5,
t15 = n / 15;
unsigned long long res_3 = 3ULL * ((t3 * (t3 + 1)) / 2ULL);
unsigned long long res_5 = 5ULL * ((t5 * (t5 + 1)) / 2ULL);
unsigned long long res_15 = 15LL * ((t15 * (t15 + 1)) / 2ULL);
return (unsigned int)(res_3 + res_5 - res_15);
}
In fact you don't need t3, t5 and t15 to be unsigned long long as those values would never overflow unsigned int.

Related

Solving Google Kickstart 2018 round c Q3

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.

Calculate Huge Fibonacci number modulo M in C++

Problem statement : Given two integers n and m, output Fn mod m (that is, the remainder of Fn when divided by m).
Input Format. The input consists of two integers n and m given on the same line (separated by a space).
Constraints. 1 ≤ n ≤ 10^18, 2 ≤ m ≤ 10^5
Output Format. Output Fn mod m.
I tried the following program and it didn't work. The method pi is returning the right Pisano period though for any number as per http://webspace.ship.edu/msrenault/fibonacci/fiblist.htm
#include <iostream>
long long pi(long long m) {
long long result = 2;
for (long long fn2 = 1, fn1 = 2 % m, fn = 3 % m;
fn1 != 1 || fn != 1;
fn2 = fn1, fn1 = fn, fn = (fn1 + fn2) % m
) {
result++;
}
return result;
}
long long get_fibonaccihuge(long long n, long long m) {
long long periodlength = pi(m);
int patternRemainder = n % periodlength;
long long *sum = new long long[patternRemainder];
sum[0] = 0;
sum[1] = 1;
for (int i = 2; i <= patternRemainder; ++i)
{
sum[i] = sum[i - 1] + sum[i - 2];
}
return sum[patternRemainder] % m;
}
int main() {
long long n, m;
std::cin >> n >> m;
std::cout << get_fibonaccihuge(n, m) << '\n';
}
The exact program/logic is working well in python as expected. What's wrong withthis cpp program ? Is it the data types ?
Performing 10^18 additions isn't going to be very practical. Even on a teraflop computer, 10^6 seconds is still 277 hours.
But 10^18 ~= 2^59.8 so there'll be up to 60 halving steps.
Calculate (a,b) --> (a^2 + b^2, 2ab + b^2) to go from (n-1,n)th to (2n-1,2n)th consecutive Fibonacci number pairs in one step.
At each step perform the modulus calculation for each operation. You'll need to accommodate integers up to 3*1010 &leq; 235 in magnitude (i.e. up to 35 bits).
(cf. a related older answer of mine).
This was my solution for this problem, it works well and succeeded in the submission test ...
i used a simpler way to get the pisoano period ( pisano period is the main tricky part in this problem ) ... i wish to be helpful
#include <iostream>
using namespace std;
unsigned long long get_fibonacci_huge_naive(unsigned long long n, unsigned long long m)
{
if (n <= 1)
return n;
unsigned long long previous = 0;
unsigned long long current = 1;
for (unsigned long long i = 0; i < n - 1; ++i)
{
unsigned long long tmp_previous = previous;
previous = current;
current = tmp_previous + current;
}
return current % m;
}
long long get_pisano_period(long long m)
{
long long a = 0, b = 1, c = a + b;
for (int i = 0; i < m * m; i++)
{
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
{
return i + 1;
}
}
}
unsigned long long get_fibonacci_huge_faster(unsigned long long n, unsigned long long m)
{
n = n % get_pisano_period(m);
unsigned long long F[n + 1] = {};
F[0] = 0;
F[-1] = 1;
for (int i = 1; i <= n; i++)
{
F[i] = F[i - 1] + F[i - 2];
F[i] = F[i] % m;
}
return F[n];
}
int main()
{
unsigned long long n, m;
std::cin >> n >> m;
std::cout << get_fibonacci_huge_faster(n, m) << '\n';
}

Why does using a (long long) cast in this code change the result?

I wrote these code for the question in link https://www.codechef.com/JAN16/problems/RGAME
code 1>>
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main(){
long long int t[100001],i,MOD=1000000007;
t[0]=1;
for(i=1;i<100001;i++){
t[i]=(t[i-1]*2)%MOD;
//cout<<t[i]<<endl;
}
int test;
cin>>test;
long long int n,a[100001];
while(test--){
cin>>n;
for(i=0;i<=n;i++)
cin>>a[i];
long long int j=(2*a[0])%MOD;
long long int s=0;
for(i=1;i<=n;i++){
int x = (j * ((a[i] * t[n - i]) % MOD)) % MOD;
s = (s+ x) % MOD;
j = (j + (a[i] * t[i]) % MOD) % MOD;
}
cout<<s<<endl;
}
return 0;
}
code 2>>
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main(){
long long int t[100001],i,MOD=1000000007;
t[0]=1;
for(i=1;i<100001;i++){
t[i]=(t[i-1]*2)%MOD;
//cout<<t[i]<<endl;
}
int test;
cin>>test;
long long int n,a[100001];
while(test--){
cin>>n;
for(i=0;i<=n;i++)
cin>>a[i];
long long int j=(2*a[0])%MOD;
long long int s=0;
for(i=1;i<=n;i++){
int x = ((long long)(j) * (((long long)(a[i]) * t[n - i]) % MOD)) % MOD;
s = (s+ x) % MOD;
j = (j + ((long long)(a[i]) * t[i]) % MOD) % MOD;
}
cout<<s<<endl;
}
return 0;
}
It can be seen that in code 1 I haven't type-casted variables j and a[i] while calculations in for loop, although they are declared as long long. and in code 2, I've used typecasting.
As per my knowledge, there is no difference between both codes. But while submitting I got wrong answer for code 1 and accepted for code 2. So it seems to me that type-casting done within for loop is quit necessary, can anybody tell me why so?
try this
int x = (((a[i] * t[n - i]) % MOD) * j) % MOD;
s = (s + x) % MOD;
j = ((a[i] * t[i]) % MOD + j) % MOD;
if you want to add two different values, put the longer one first...
EDIT:
if s + x > 2^^31 - 1, another type conversion is required:
s = (1LL * s + x) % MOD;

Combinations of large number in c++

How to compute combination for large number in c++? (eg. nCr n=1000 and r=500) Requirement is of last 9 digits of combination. I tried using long long int variable but still my code is able to solve and display last 9 digits of 50C19 but not more than that.
const long int a = 1000000000;
long long int ncr(int n,int r)
{
long long int fac1 = 1,fac2=1,fac;
for(int i=r;i>=1;i--,n--)
{
fac1 = fac1 * n;
if(fac1%i==0)
fac1 = fac1/i;
else
fac2 = fac2 * i;
}
fac = fac1/fac2;
return fac%a;
}
Just store the factors of the numerator in an array and divide out each factor of the denominator where possible. Finally take the product of the reduced numerators mod 10^9.
Here is some code for your specific example. You need to write a gcd() function.
int a[] = { 1000,999,...,501 }; // numerator factors
for (int b = 2; b <= 500; b++) {
int x = b;
for (int i = 0; i < 500; i++) {
int d = gcd(x, a[i]);
if (d > 1) {
x = x / d;
a[i] = a[i] / d;
if (x <= 1) break;
}
}
}
// take the product of a[] mod 10^9
int ans = 1;
for (int i = 0; i < 500; i++) {
ans = (ans * a[i]) % 1000000000;
}
// ans = C(1000,500) mod 10^9
A good discussion of other techniques is available here:
http://discuss.codechef.com/questions/3869/best-known-algos-for-calculating-ncr-m

nCk modulo p when n % p or k % p == 0

I'm trying to solve a coding challenge on hacker rank which requires one to calculate binomial coefficients mod a prime, i.e.
nchoosek(n, k, p)
I'm using the code from this answer that works for the first three sets of inputs but begins failing on the 4th. I stepped through it in the debugger and determined that the issue arises when:
n % p == 0 || k % p == 0
I just need to know how to modify my current solution to handle the specific cases where n % p == 0 or k % p == 0. None of the answers I've found on stack exchange seem to address this specific case. Here's my code:
#include <iostream>
#include <fstream>
long long FactorialExponent(long long n, long long p)
{
long long ex = 0;
do
{
n /= p;
ex += n;
}while(n > 0);
return ex;
}
unsigned long long ModularMultiply(unsigned long long a, unsigned long long b, unsigned long p) {
unsigned long long a1 = (a >> 21), a2 = a & ((1ull << 21) - 1);
unsigned long long temp = (a1 * b) % p; // doesn't overflow under the assumptions
temp = (temp << 21) % p; // this neither
temp += (a2 * b) % p; // nor this
return temp % p;
}
unsigned long long ModularInverse(unsigned long long k, unsigned long m) {
if (m == 0) return (k == 1 || k == -1) ? k : 0;
if (m < 0) m = -m;
k %= m;
if (k < 0) k += m;
int neg = 1;
unsigned long long p1 = 1, p2 = 0, k1 = k, m1 = m, q, r, temp;
while(k1 > 0) {
q = m1 / k1;
r = m1 % k1;
temp = q*p1 + p2;
p2 = p1;
p1 = temp;
m1 = k1;
k1 = r;
neg = !neg;
}
return neg ? m - p2 : p2;
}
// Preconditions: 0 <= k <= min(n,p-1); p > 1 prime
unsigned long long ChooseModTwo(unsigned long long n, unsigned long long k, unsigned long p)
{
// reduce n modulo p
n %= p;
// Trivial checks
if (n < k) {
return 0;
}
if (k == 0 || k == n) {
return 1;
}
// Now 0 < k < n, save a bit of work if k > n/2
if (k > n/2) {
k = n-k;
}
// calculate numerator and denominator modulo p
unsigned long long num = n, den = 1;
for(n = n-1; k > 1; --n, --k)
{
num = ModularMultiply(num, n, p);
den = ModularMultiply(den, k, p);
}
den = ModularInverse(den,p);
return ModularMultiply(num, den, p);
}
// Preconditions: 0 <= k <= n; p > 1 prime
long long ChooseModOne(long long n, long long k, const unsigned long p)
{
// For small k, no recursion is necessary
if (k < p) return ChooseModTwo(n,k,p);
unsigned long long q_n, r_n, q_k, r_k, choose;
q_n = n / p;
r_n = n % p;
q_k = k / p;
r_k = k % p;
choose = ChooseModTwo(r_n, r_k, p);
// If the exponent of p in choose(n,k) isn't determined to be 0
// before the calculation gets serious, short-cut here:
// if (choose == 0) return 0;
return ModularMultiply(choose, ChooseModOne(q_n, q_k, p), p);
}
unsigned long long ModularBinomialCoefficient(unsigned long long n, unsigned long long k, const unsigned long p)
{
// We deal with the trivial cases first
if (k < 0 || n < k) return 0;
if (k == 0 || k == n) return 1;
// Now check whether choose(n,k) is divisible by p
if (FactorialExponent(n, p) > FactorialExponent(k, p) + FactorialExponent(n - k, p)) return 0;
// If it's not divisible, do the generic work
return ChooseModOne(n, k, p);
}
int main() {
//std::ifstream fin ("input03.txt");
std::ifstream fin ("test.in");
int kMod = 1000003;
int T;
fin >> T;
int N = T;
//std::cin >> T;
unsigned long long n, k;
unsigned long long a, b;
int result[N];
int index = 0;
while (T--) {
fin >> n >> k;
a = ModularBinomialCoefficient(n - 3, k, kMod);
b = ModularBinomialCoefficient(n + k, n - 1, kMod);
// (1 / (n + k) * nCk(n - 3, k) * nCk(n + k, n - 1)) % 1000003
unsigned long long x = ModularMultiply(a, b, kMod);
unsigned long long y = ModularMultiply(x, ModularInverse((n + k), kMod), kMod);
result[index] = y;
index++;
}
for(int i = 0; i < N; i++) {
std::cout << result[i] << "\n";
}
return 0;
}
Input:
6
90 13
65434244 16341234
23424244 12341234
424175 341198
7452123 23472
56000168 16000048
Output:
815483
715724
92308
903465
241972
0 <-- Incorrect, should be: 803478
Constraints:
4 <= N <= 10^9
1 <= K <= N
You can use Lucas' theorem to reduce the problem to ceil(log_P(N)) subproblems with k, n < p: Write n = n_m * p^m + ... + n_0 and k = k_m * p^m + ... + k_0 in base p (n_i, k_i < p are the digits), then we have
C(n,k) = PROD(i = 0 to m, C(n_i, k_i)) (mod p)
The subproblems are easy to solve, because every factor of k! has an inverse modulo p. You get an algorithm with runtime complexity O(p log(n)), which is better than that of Ivaylo's code in case of p << n, if I understand it correctly.
int powmod(int x, int e, int p) {
if (e == 0) return 1;
if (e & 1) return (long long)x * powmod(x, e - 1, p) % p;
long long rt = powmod(x, e / 2, p);
return rt * rt % p;
}
int binom_coeff_mod_prime(int n, int k, int p) {
long long res = 1;
while (n || k) {
int N = n % p, K = k % p;
for (int i = N - K + 1; i <= N; ++i)
res = res * i % p;
for (int i = 1; i <= K; ++i)
res = res * powmod(i, p - 2, p) % p;
n /= p;
k /= p;
}
return res;
}
I suggest you use factorization to compute the number of combinations without division. I've got code for doing so here, originally inspired by Fast computation of multi-category number of combinations (I still would like to post a proper answer to that, if some kind souls would reopen it).
My code stores the result as a table of factors, doing the modular multiplication to expand the result should be quite straightforward.
Probably not practical for n in the range of 10**9, though, since the sieve will be quite massive and take a while to construct.