49 changed files with 1044 additions and 0 deletions
-
12algorithms-and-datastructures/fenwick/Makefile
-
2algorithms-and-datastructures/fenwick/a0
-
2algorithms-and-datastructures/fenwick/a1
-
11algorithms-and-datastructures/fenwick/a2
-
5algorithms-and-datastructures/fenwick/d0
-
5algorithms-and-datastructures/fenwick/d1
-
13algorithms-and-datastructures/fenwick/d2
-
123algorithms-and-datastructures/fenwick/main.cpp
-
12algorithms-and-datastructures/fft/Makefile
-
5algorithms-and-datastructures/fft/d0
-
5algorithms-and-datastructures/fft/d1
-
9algorithms-and-datastructures/fft/d2
-
5algorithms-and-datastructures/fft/d3
-
5algorithms-and-datastructures/fft/d4
-
5algorithms-and-datastructures/fft/d5
-
5algorithms-and-datastructures/fft/d6
-
5algorithms-and-datastructures/fft/d8
-
196algorithms-and-datastructures/fft/main.cpp
-
12algorithms-and-datastructures/modular-arithmetic/Makefile
-
10algorithms-and-datastructures/modular-arithmetic/d0
-
11algorithms-and-datastructures/modular-arithmetic/d1
-
3algorithms-and-datastructures/modular-arithmetic/d10
-
4algorithms-and-datastructures/modular-arithmetic/d11
-
11algorithms-and-datastructures/modular-arithmetic/d12
-
1algorithms-and-datastructures/modular-arithmetic/d13
-
3algorithms-and-datastructures/modular-arithmetic/d14
-
36algorithms-and-datastructures/modular-arithmetic/d2
-
23algorithms-and-datastructures/modular-arithmetic/d3
-
3algorithms-and-datastructures/modular-arithmetic/d4
-
16algorithms-and-datastructures/modular-arithmetic/d5
-
16algorithms-and-datastructures/modular-arithmetic/d6
-
6algorithms-and-datastructures/modular-arithmetic/d7
-
14algorithms-and-datastructures/modular-arithmetic/d8
-
4algorithms-and-datastructures/modular-arithmetic/d9
-
129algorithms-and-datastructures/modular-arithmetic/main.cpp
-
12algorithms-and-datastructures/prime-sieve/Makefile
-
7algorithms-and-datastructures/prime-sieve/d0
-
28algorithms-and-datastructures/prime-sieve/d1
-
3algorithms-and-datastructures/prime-sieve/d2
-
3algorithms-and-datastructures/prime-sieve/d3
-
4algorithms-and-datastructures/prime-sieve/d4
-
4algorithms-and-datastructures/prime-sieve/d5
-
113algorithms-and-datastructures/prime-sieve/main.cpp
-
12algorithms-and-datastructures/unionfind/Makefile
-
5algorithms-and-datastructures/unionfind/d0
-
9algorithms-and-datastructures/unionfind/d1
-
5algorithms-and-datastructures/unionfind/d2
-
6algorithms-and-datastructures/unionfind/d3
-
106algorithms-and-datastructures/unionfind/main.cpp
@ -0,0 +1,12 @@ |
|||
EXECUTABLE=a.out |
|||
CC=g++ |
|||
CFLAGS=-g -lm -O2 -std=c++17 -Wall -Wextra |
|||
OBJ=main.cpp |
|||
|
|||
$(EXECUTABLE): $(OBJ) |
|||
$(CC) $(CFLAGS) -o $@ -static $(OBJ) |
|||
|
|||
.PHONY: clean |
|||
clean: |
|||
rm -rf $(EXECUTABLE) |
|||
|
|||
@ -0,0 +1,2 @@ |
|||
23 |
|||
40 |
|||
@ -0,0 +1,2 @@ |
|||
0 |
|||
-42 |
|||
@ -0,0 +1,11 @@ |
|||
0 |
|||
0 |
|||
0 |
|||
0 |
|||
0 |
|||
1 |
|||
1 |
|||
1 |
|||
1 |
|||
1 |
|||
1 |
|||
@ -0,0 +1,5 @@ |
|||
10 4 |
|||
+ 7 23 |
|||
? 8 |
|||
+ 3 17 |
|||
? 8 |
|||
@ -0,0 +1,5 @@ |
|||
5 4 |
|||
+ 0 -43 |
|||
+ 4 1 |
|||
? 0 |
|||
? 5 |
|||
@ -0,0 +1,13 @@ |
|||
16 12 |
|||
+ 8 1 |
|||
? 4 |
|||
? 5 |
|||
? 6 |
|||
? 7 |
|||
? 8 |
|||
? 9 |
|||
? 10 |
|||
? 11 |
|||
? 12 |
|||
? 13 |
|||
? 14 |
|||
@ -0,0 +1,123 @@ |
|||
/*
|
|||
* Author: André Palmborg |
|||
* |
|||
* Course: TDDD95 |
|||
* Task: 1.5: Fenwick |
|||
*/ |
|||
|
|||
#include <stdio.h>
|
|||
#include <stdlib.h>
|
|||
|
|||
|
|||
|
|||
// Fenwick Tree
|
|||
//
|
|||
// Stores partial cumulative sums of a value array in a binary indexed tree:
|
|||
//
|
|||
// 0
|
|||
// |---------------8
|
|||
// |-------4 |---------12
|
|||
// |---2 |---6 |---10 |-----14
|
|||
// |-1 |-3 |-5 |-7 |-9 |--11 |--13 |--15
|
|||
//
|
|||
// Position 8 stores the sum from 0 to 8.
|
|||
// So to calculate the sum from 0 to 13 only the partial sums at
|
|||
// position 8, 12 and 13 need to be accessed.
|
|||
template<typename T> |
|||
struct Fenwick_Tree |
|||
{ |
|||
T* tree; |
|||
size_t size; |
|||
Fenwick_Tree(size_t N) |
|||
{ |
|||
tree = (T*) malloc(N * sizeof(T)); |
|||
size = N; |
|||
for (size_t i = 0; i < size; i++) |
|||
{ |
|||
tree[i] = 0; |
|||
} |
|||
}; |
|||
~Fenwick_Tree() |
|||
{ |
|||
delete[] tree; |
|||
}; |
|||
|
|||
|
|||
// Add &d to hypothetical value array at index &i
|
|||
void add(long int i, T d) |
|||
{ |
|||
while (i <= (long int)size) |
|||
{ |
|||
tree[i] += d; |
|||
if (i == 0) |
|||
i++; |
|||
else |
|||
i += ((i) & -(i)); // Add least sig. bit
|
|||
} |
|||
}; |
|||
|
|||
// Base sum function
|
|||
T _sum(long int i) |
|||
{ |
|||
T sum = 0; |
|||
while (i > 0) |
|||
{ |
|||
sum += tree[i]; |
|||
i -= ((i) & -(i)); // Remove least sig. bit
|
|||
} |
|||
return sum; |
|||
}; |
|||
|
|||
// Sums the range [l,r]
|
|||
T sumRange(long int l, long int r) |
|||
{ |
|||
return _sum(r) - _sum(l-1); |
|||
}; |
|||
|
|||
// Sums the range [0,r) non inclusive on right side
|
|||
T sumUpTo(long int i) |
|||
{ |
|||
if (i == 0) |
|||
return 0; |
|||
else if (i == 1) |
|||
return tree[0]; |
|||
else |
|||
return _sum(i-1); |
|||
}; |
|||
|
|||
// Debug for prints
|
|||
T get(size_t i) |
|||
{ |
|||
return tree[i]; |
|||
}; |
|||
}; |
|||
|
|||
|
|||
|
|||
int main() |
|||
{ |
|||
unsigned N, Q; |
|||
scanf("%u %u ", &N, &Q); |
|||
Fenwick_Tree<long int> t(N); |
|||
|
|||
char op; |
|||
unsigned i; |
|||
long int d, s; |
|||
while (0 < Q--) |
|||
{ |
|||
scanf("%c ", &op); |
|||
if (op == '+') |
|||
{ |
|||
scanf("%u %ld ", &i, &d); |
|||
t.add(i, d); |
|||
} |
|||
else if (op == '?') |
|||
{ |
|||
scanf("%u ", &i); |
|||
s = t.sumUpTo(i); |
|||
printf("%ld\n", s); |
|||
} |
|||
else |
|||
puts("Throws exception... Lazily"); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
EXECUTABLE=a.out |
|||
CC=g++ |
|||
CFLAGS=-g -lm -O2 -std=gnu++17 -Wall -Wextra |
|||
OBJ=main.cpp |
|||
|
|||
$(EXECUTABLE): $(OBJ) |
|||
$(CC) $(CFLAGS) -o $@ -static $(OBJ) |
|||
|
|||
.PHONY: clean |
|||
clean: |
|||
rm -rf $(EXECUTABLE) |
|||
|
|||
@ -0,0 +1,5 @@ |
|||
1 |
|||
2 |
|||
1 0 5 |
|||
1 |
|||
0 -2 |
|||
@ -0,0 +1,5 @@ |
|||
1 |
|||
6 |
|||
1 1 1 1 1 1 2 |
|||
2 |
|||
0 0 1 |
|||
@ -0,0 +1,9 @@ |
|||
2 |
|||
2 |
|||
1 0 5 |
|||
1 |
|||
0 -2 |
|||
4 |
|||
1 1 -1 1 1 |
|||
4 |
|||
9 -8 7 6 5 |
|||
@ -0,0 +1,5 @@ |
|||
1 |
|||
5 |
|||
0 1 0 -1 0 50 |
|||
1 |
|||
1 -2 |
|||
@ -0,0 +1,5 @@ |
|||
1 |
|||
6 |
|||
1 1 1 1 1 1 2 |
|||
1 |
|||
0 0 |
|||
@ -0,0 +1,5 @@ |
|||
1 |
|||
2 |
|||
1 0 5 |
|||
1 |
|||
0 -2 |
|||
@ -0,0 +1,5 @@ |
|||
1 |
|||
4 |
|||
1 1 -1 1 1 |
|||
4 |
|||
9 -8 7 6 5 |
|||
@ -0,0 +1,5 @@ |
|||
1 |
|||
1 |
|||
0 7 |
|||
1 |
|||
0 -7 |
|||
@ -0,0 +1,196 @@ |
|||
/*
|
|||
* Author: André Palmborg |
|||
* |
|||
* Course: TDDD95 |
|||
* Task: 1.6: polymul2 |
|||
*/ |
|||
|
|||
#include <stdio.h>
|
|||
#include <stdlib.h>
|
|||
|
|||
#include <stdexcept>
|
|||
|
|||
#include <complex>
|
|||
typedef std::complex<long double> C; |
|||
const double PI = 3.141592653589793238460; |
|||
|
|||
#include <valarray>
|
|||
using std::valarray; |
|||
typedef std::valarray<C> Carray; |
|||
|
|||
|
|||
|
|||
/* FFT_h
|
|||
* |
|||
* Performs the inverse and regular Fast Fourier Transform using |
|||
* the Cooley-Tukey algorithm on a valarray of samples. |
|||
* |
|||
* Input |
|||
* Carray& samples : Valarray of complex<long double> samples. |
|||
* size_t N : The size of the $samples valarray. |
|||
* bool inv : Boolean telling FFT_h if it should compute the inverse FFT. |
|||
* |
|||
* Returns void : Transformed values are placed in the referenced $samples array |
|||
*/ |
|||
void FFT_h(Carray& samples, size_t N, bool inv) |
|||
{ |
|||
double f = (inv) ? 2 : -2; |
|||
|
|||
if (N != 1) |
|||
{ |
|||
Carray even = samples[std::slice(0, N/2, 2)]; |
|||
Carray odd = samples[std::slice(1, N/2, 2)]; |
|||
|
|||
FFT_h(even, N/2, inv); |
|||
FFT_h(odd, N/2, inv); |
|||
|
|||
for (size_t i{0}; i < N/2; i++) |
|||
{ |
|||
// DEBUG
|
|||
//printf("loop: (%lu) : max_i=%lu\n", i, i + N/2);
|
|||
C t = even[i]; |
|||
C exp = std::polar(1.0L, (long double)f * PI * i / N) * odd[i]; |
|||
samples[i] = t + exp; |
|||
samples[i + N/2] = t - exp; |
|||
} |
|||
} |
|||
} |
|||
// Maps regular or inverse FFT calls to FFT_h with the correct
|
|||
// coefficient; 2 for FFT and -2 for inverse FFT
|
|||
void FFT(Carray& samples) {FFT_h(samples, samples.size(), false);} |
|||
void iFFT(Carray& samples) {FFT_h(samples, samples.size(), true);} |
|||
|
|||
|
|||
/* pMultiplication
|
|||
* Pointwise multiplication of two Complex valarrays |
|||
* |
|||
* Side-effects : Will throw an exception if the given arrays are not the exact same size. |
|||
* |
|||
* Returns Carray P: New Carray with same length as A and B |
|||
* */ |
|||
Carray pointMultiplication(Carray& A, Carray& B) |
|||
{ |
|||
if (A.size() != B.size()) |
|||
throw std::invalid_argument("Pointwise array multiplication with differing array length"); |
|||
|
|||
Carray P; |
|||
P.resize(A.size()); |
|||
for (size_t i{0}; i < A.size(); i++) {P[i] = A[i] * B[i];} |
|||
return P; |
|||
} |
|||
|
|||
|
|||
/* inputArray
|
|||
* |
|||
* Takes one polynomial from input and places it, in coefficient form, in |
|||
* a referenced array. |
|||
* |
|||
* Side-effect: Removes input described below incl. last newline from stdin. |
|||
* stdin : ^deg$ |
|||
* ^c_0 c_1 ... c_deg$ |
|||
*/ |
|||
int inputArray(Carray& a) |
|||
{ |
|||
size_t a_size; |
|||
scanf("%lu", &a_size); |
|||
a.resize( (a_size+1) ); |
|||
|
|||
int z = 1; |
|||
long int n; |
|||
for (size_t i{0}; i <= a_size; i++) |
|||
{ |
|||
scanf("%lu ", &n); |
|||
if (n != 0) {z = 0;} |
|||
a[i] = (C)n; |
|||
} |
|||
return z; |
|||
} |
|||
|
|||
|
|||
/* takeInput
|
|||
* |
|||
* Takes two polynomials from input and places them, in coefficient form, in two referenced arrays. |
|||
* |
|||
* Returns 1 if one or more of the arrays are equal to 0 |
|||
* Returns 0 otherwise |
|||
*/ |
|||
int takeInput(Carray& a, Carray& b) |
|||
{ |
|||
if (inputArray(a) == 1 || inputArray(b) == 1) |
|||
return 1; |
|||
else |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
/* polynomialMultiplication
|
|||
* |
|||
* Polynomial multiplication using the Fast Fourier Transform. |
|||
* |
|||
* a * b = iFFT( FFT(b) .* FFT(b) ) |
|||
* Where * is normal polynomial multiplication and .* is pointwise multiplication. |
|||
* |
|||
* Side-effects: Will attempt to read two polynomials from stdin. |
|||
* When computed the result will be sent to stdout. |
|||
*/ |
|||
void polynomialMultiplication() |
|||
{ |
|||
Carray a; |
|||
Carray b; |
|||
int z = takeInput(a, b); |
|||
|
|||
// Handles cases where one or more of the arrays are equal to zero
|
|||
if (z == 1) { puts("0\n0"); return; } |
|||
|
|||
size_t s = (a.size() < b.size()) ? b.size() : a.size(); |
|||
size_t e = 1; |
|||
while (e < s) { e<<=1; } |
|||
|
|||
// Create new zero-padded arrays of length e*2 where e is the smallest
|
|||
// power of 2 larger than max(a.size(), b.size()).
|
|||
Carray A; |
|||
A.resize(e*2); |
|||
for (size_t i{0}; i < a.size(); i++) {A[i] = a[i];} |
|||
Carray B; |
|||
B.resize(e*2); |
|||
for (size_t i{0}; i < b.size(); i++) {B[i] = b[i];} |
|||
|
|||
// Multiply polynomials
|
|||
FFT(A); |
|||
FFT(B); |
|||
Carray P = pointMultiplication(A, B); |
|||
iFFT(P); |
|||
|
|||
// Get the degree of the resulting polynomial.
|
|||
size_t max_i{0}; |
|||
for (size_t i{0}; i < P.size(); i++) |
|||
{ |
|||
if ( 1e-1 < std::abs(P[i].real()) ) {max_i = i+1;} |
|||
} |
|||
printf("%lu\n", max_i-1); |
|||
|
|||
// Print rounded coefficients of the resulting polynomial.
|
|||
long int f, c; |
|||
long double v; |
|||
for (size_t i{0}; i < max_i; i++) |
|||
{ |
|||
f = (long int)std::floor(P[i].real()/P.size()); |
|||
c = f + 1; |
|||
v = P[i].real()/P.size(); |
|||
if (v - (long double)f < (long double)c - v) |
|||
printf("%ld ", f); |
|||
else |
|||
printf("%ld ", c); |
|||
} |
|||
fputs("\n", stdout); |
|||
} |
|||
|
|||
|
|||
/* Repeats per test case to solve polymul1 and polymul2 */ |
|||
int main() |
|||
{ |
|||
int z; |
|||
scanf("%d ", &z); |
|||
for (int i{0}; i < z; i++) { polynomialMultiplication(); } |
|||
} |
|||
|
|||
@ -0,0 +1,12 @@ |
|||
EXECUTABLE=a.out |
|||
CC=g++ |
|||
CFLAGS=-g -lm -O2 -std=gnu++17 -Wall -Wextra -Weffc++ |
|||
OBJ=main.cpp |
|||
|
|||
$(EXECUTABLE): $(OBJ) |
|||
$(CC) $(CFLAGS) -o $@ -static $(OBJ) |
|||
|
|||
.PHONY: clean |
|||
clean: |
|||
rm -rf $(EXECUTABLE) |
|||
|
|||
@ -0,0 +1,10 @@ |
|||
1000 3 |
|||
1 / 999 |
|||
1 / 998 |
|||
578 * 178 |
|||
13 4 |
|||
7 / 9 |
|||
9 * 3 |
|||
0 - 9 |
|||
10 + 10 |
|||
0 0 |
|||
@ -0,0 +1,11 @@ |
|||
1000 4 |
|||
1 / 999 |
|||
1 / 998 |
|||
578 / 178 |
|||
578 / 177 |
|||
13 4 |
|||
7 / 9 |
|||
9 / 3 |
|||
0 / 9 |
|||
10 / 10 |
|||
0 0 |
|||
@ -0,0 +1,3 @@ |
|||
1000000000000000000 1 |
|||
999999999999999999 / 999999999999999999 |
|||
0 0 |
|||
@ -0,0 +1,4 @@ |
|||
1000000000000000000 2 |
|||
999999999999999999 * 999999999999999999 |
|||
999999999999999999 * 999999999999999997 |
|||
0 0 |
|||
@ -0,0 +1,11 @@ |
|||
1000 4 |
|||
1 / 999 |
|||
1 / 998 |
|||
578 / 178 |
|||
578 / 177 |
|||
13 4 |
|||
7 / 9 |
|||
9 / 3 |
|||
0 / 9 |
|||
10 / 10 |
|||
0 0 |
|||
@ -0,0 +1 @@ |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
780205311 1 |
|||
0 / 27094470 |
|||
0 0 |
|||
@ -0,0 +1,36 @@ |
|||
10 22 |
|||
0 + 1 |
|||
0 + 2 |
|||
0 + 3 |
|||
0 + 4 |
|||
0 + 5 |
|||
0 + 6 |
|||
0 + 7 |
|||
0 + 8 |
|||
0 + 9 |
|||
0 + 10 |
|||
0 + 11 |
|||
5 + 1 |
|||
5 + 2 |
|||
5 + 3 |
|||
5 + 4 |
|||
5 + 5 |
|||
5 + 6 |
|||
5 + 7 |
|||
5 + 8 |
|||
5 + 9 |
|||
5 + 10 |
|||
5 + 11 |
|||
5 11 |
|||
1 * 0 |
|||
1 * 1 |
|||
1 * 2 |
|||
1 * 3 |
|||
1 * 4 |
|||
1 * 5 |
|||
1 * 6 |
|||
1 * 7 |
|||
1 * 8 |
|||
1 * 9 |
|||
1 * 10 |
|||
0 0 |
|||
@ -0,0 +1,23 @@ |
|||
5 21 |
|||
1 / 0 |
|||
1 / 1 |
|||
1 / 2 |
|||
1 / 3 |
|||
1 / 4 |
|||
1 / 5 |
|||
1 / 6 |
|||
3 / 0 |
|||
3 / 1 |
|||
3 / 2 |
|||
3 / 3 |
|||
3 / 4 |
|||
3 / 5 |
|||
3 / 6 |
|||
5 / 0 |
|||
5 / 1 |
|||
5 / 2 |
|||
5 / 3 |
|||
5 / 4 |
|||
5 / 5 |
|||
5 / 6 |
|||
0 0 |
|||
@ -0,0 +1,3 @@ |
|||
5 1 |
|||
3 / 2 |
|||
0 0 |
|||
@ -0,0 +1,16 @@ |
|||
7 14 |
|||
0 / 5 |
|||
1 / 5 |
|||
2 / 5 |
|||
3 / 5 |
|||
4 / 5 |
|||
5 / 5 |
|||
6 / 5 |
|||
7 / 5 |
|||
8 / 5 |
|||
9 / 5 |
|||
10 / 5 |
|||
11 / 5 |
|||
12 / 5 |
|||
13 / 5 |
|||
0 0 |
|||
@ -0,0 +1,16 @@ |
|||
7 14 |
|||
0 / 5 |
|||
1 / 5 |
|||
2 / 5 |
|||
3 / 5 |
|||
4 / 5 |
|||
5 / 5 |
|||
6 / 5 |
|||
7 / 5 |
|||
-6 / 5 |
|||
-5 / 5 |
|||
-4 / 5 |
|||
-3 / 5 |
|||
-2 / 5 |
|||
-1 / 5 |
|||
0 0 |
|||
@ -0,0 +1,6 @@ |
|||
1 4 |
|||
1 / 1 |
|||
0 / 1 |
|||
1 / 0 |
|||
3 * 3 |
|||
0 0 |
|||
@ -0,0 +1,14 @@ |
|||
2 4 |
|||
1 / 1 |
|||
0 / 1 |
|||
1 / 0 |
|||
3 * 3 |
|||
2 2 |
|||
2 / 1 |
|||
2 / 2 |
|||
7 4 |
|||
1 / 14 |
|||
0 / 14 |
|||
0 / 0 |
|||
0 * 6 |
|||
0 0 |
|||
@ -0,0 +1,4 @@ |
|||
1000000000000000000 2 |
|||
1 / 999999999999999998 |
|||
999999999999999999 / 999999999999999999 |
|||
0 0 |
|||
@ -0,0 +1,129 @@ |
|||
#include <stdexcept>
|
|||
#include <stdio.h>
|
|||
|
|||
#define ll long long int
|
|||
|
|||
|
|||
inline void add(ll lhs, ll rhs, ll n) |
|||
{ |
|||
ll out = lhs+rhs; |
|||
if( out < 0 ) |
|||
out += n; |
|||
printf("%lld\n", (lhs+rhs)%n); |
|||
} |
|||
inline void sub(ll lhs, ll rhs, ll n) |
|||
{ |
|||
ll out = lhs-rhs; |
|||
while( out < 0 ) |
|||
out += n; |
|||
printf("%lld\n", out%n); |
|||
} |
|||
inline void mul(ll lhs, ll rhs, ll n) |
|||
{ |
|||
//if (lhs < 0 || rhs < 0) throw std::invalid_argument("BAD");
|
|||
ll out = lhs*rhs; |
|||
while( out < 0 ) |
|||
out += n; |
|||
printf("%lld\n", out%n); |
|||
} |
|||
|
|||
bool extEuclid(ll m, ll n, ll &a, ll &b) |
|||
{ |
|||
ll a1 = 1; |
|||
ll b1 = 0; |
|||
a = 0; |
|||
b = 1; |
|||
|
|||
ll c = m; |
|||
ll d = n; |
|||
ll q; |
|||
ll r; |
|||
if (d == 0) return false; |
|||
|
|||
ll t; |
|||
while (true) |
|||
{ |
|||
q = c/d; |
|||
r = c%d; |
|||
//printf("a'(%lld) a(%lld) b'(%lld) b(%lld) c(%lld) d(%lld) q(%lld) r(%lld)\n", a1, a, b1, b, c, d, q, r);
|
|||
if (r == 0) break; |
|||
|
|||
c = d; |
|||
d = r; |
|||
|
|||
t = a1; |
|||
a1 = a; |
|||
a = t - q*a; |
|||
|
|||
t = b1; |
|||
b1 = b; |
|||
b = t - q*b; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
inline void div(ll lhs, ll rhs, ll n) |
|||
{ |
|||
//printf("lhs(%lld) rhs(%lld)\n", lhs, rhs);
|
|||
if( rhs == 0 ) { puts("-1"); return; } |
|||
//else if( lhs == 0 ) { puts("0"); return; }
|
|||
|
|||
|
|||
ll a, inv; |
|||
if( extEuclid(n, rhs, a, inv) && n*a + rhs*inv == 1 ) |
|||
{ |
|||
//printf("lhs(%lld) inv(%lld)\n", lhs, inv);
|
|||
//printf("sum: %d\n", n*a + rhs*inv);
|
|||
while( inv < 0 ) |
|||
inv += n; |
|||
inv %= n; |
|||
mul( lhs, inv, n ); |
|||
} |
|||
else |
|||
{ |
|||
puts("-1"); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
|
|||
int main() |
|||
{ |
|||
ll n; |
|||
int nOps; |
|||
|
|||
char op; |
|||
ll lhs, rhs; |
|||
|
|||
scanf("%lld %d ", &n, &nOps); |
|||
while( !(n == 0 && nOps == 0) ) |
|||
{ |
|||
//printf("n(%lld) nOps(%d)\n", n, nOps);
|
|||
while(nOps--) |
|||
{ |
|||
scanf("%lld %c %lld ", &lhs, &op, &rhs); |
|||
lhs %= n; |
|||
rhs %= n; |
|||
//printf("lhs(%lld) op(%c) rhs(%lld)\n", lhs, op, rhs);
|
|||
|
|||
switch( op ) |
|||
{ |
|||
case '+': add(lhs, rhs, n); |
|||
break; |
|||
case '-': sub(lhs, rhs, n); |
|||
break; |
|||
case '*': mul(lhs, rhs, n); |
|||
break; |
|||
case '/': div(lhs, rhs, n); |
|||
break; |
|||
default: throw std::invalid_argument("BAD OP"); |
|||
} |
|||
|
|||
} |
|||
|
|||
scanf("%lld %d ", &n, &nOps); |
|||
} |
|||
|
|||
|
|||
return 0; |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
EXECUTABLE=a.out |
|||
CC=g++ |
|||
CFLAGS=-g -lm -O2 -std=gnu++17 -Wall -Wextra -Weffc++ |
|||
OBJ=main.cpp |
|||
|
|||
$(EXECUTABLE): $(OBJ) |
|||
$(CC) $(CFLAGS) -o $@ -static $(OBJ) |
|||
|
|||
.PHONY: clean |
|||
clean: |
|||
rm -rf $(EXECUTABLE) |
|||
|
|||
@ -0,0 +1,7 @@ |
|||
9973 6 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
9972 |
|||
9973 |
|||
@ -0,0 +1,28 @@ |
|||
100 27 |
|||
2 |
|||
3 |
|||
5 |
|||
10 |
|||
7 |
|||
11 |
|||
13 |
|||
17 |
|||
4 |
|||
19 |
|||
23 |
|||
29 |
|||
31 |
|||
37 |
|||
41 |
|||
43 |
|||
47 |
|||
53 |
|||
59 |
|||
61 |
|||
67 |
|||
71 |
|||
73 |
|||
79 |
|||
83 |
|||
89 |
|||
97 |
|||
@ -0,0 +1,3 @@ |
|||
10 2 |
|||
5 |
|||
6 |
|||
@ -0,0 +1,3 @@ |
|||
100000000 2 |
|||
5 |
|||
1000000 |
|||
@ -0,0 +1,4 @@ |
|||
1001 3 |
|||
1 |
|||
2 |
|||
1001 |
|||
@ -0,0 +1,4 @@ |
|||
9973 3 |
|||
2 |
|||
3 |
|||
5 |
|||
@ -0,0 +1,113 @@ |
|||
/*
|
|||
* Author: André Palmborg |
|||
* LiU ID: andpa149 |
|||
* |
|||
* Course: TDDD95 |
|||
* Task: 3.8: primesieve |
|||
*/ |
|||
|
|||
#include <stdio.h>
|
|||
#include <math.h>
|
|||
#include <vector>
|
|||
using std::vector; |
|||
|
|||
|
|||
|
|||
/* Sieve of Eratosthenes
|
|||
* |
|||
* Generates primes within a fixed span by successively marking of composite |
|||
* numbers divisible by primes. Starting marking from smallest prime leaves |
|||
* the next smallest prime unmarked in the vector. |
|||
* |
|||
* O( exp(N) ) time complexity |
|||
* O( N ) memory |
|||
*/ |
|||
|
|||
void eratosthenes_sieve(vector<bool>& primes, int N) |
|||
{ |
|||
int i=2; |
|||
int j; |
|||
while( true ) |
|||
{ |
|||
if( primes[i] == true && i*2 <= N ) |
|||
{ |
|||
j = 2; |
|||
while( i*j <= N ) |
|||
{ |
|||
primes[ i*j ] = false; |
|||
j++; |
|||
} |
|||
} |
|||
if( ++i == N ) break; |
|||
} |
|||
primes[0] = false; |
|||
primes[1] = false; |
|||
} |
|||
|
|||
/* is_prime
|
|||
* |
|||
* Returns wheter a given int n is prime. |
|||
* Utilizes wheel factorization with wheel size=6. |
|||
* |
|||
* O( n ) time complexity |
|||
* O( 1 ) memory |
|||
*/ |
|||
bool is_prime(int n) |
|||
{ |
|||
if( n == 2 || n == 3 ) |
|||
return true; |
|||
else if( n%2 == 0 || n%3 == 0) |
|||
return false; |
|||
|
|||
long unsigned i=5, o=0, m=3; |
|||
while( n != 1 && 0 < n && i < n/m) |
|||
{ |
|||
if( n%i == 0 ) |
|||
return false; |
|||
|
|||
m = i; |
|||
if( i%6 == 5 ) |
|||
{ |
|||
o++; |
|||
i += 2; |
|||
} |
|||
else |
|||
{ i += 4; } |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
|
|||
/*
|
|||
* |
|||
*/ |
|||
int main() |
|||
{ |
|||
int N, q; |
|||
scanf("%d ", &N); |
|||
N += 1; |
|||
vector<bool> primes(N, true); |
|||
eratosthenes_sieve(primes, N); |
|||
|
|||
// Count primes
|
|||
int nPrimes = 0; |
|||
int i=0; |
|||
while( true ) |
|||
{ |
|||
if( primes[i] == true ) nPrimes++; |
|||
if( ++i == N ) break; |
|||
} |
|||
printf("%d\n", nPrimes); |
|||
|
|||
// Handle queries
|
|||
scanf("%d ", &q); |
|||
int query; |
|||
while( 0 < q-- ) |
|||
{ |
|||
scanf("%d ", &query); |
|||
if (primes[query] == false ) |
|||
puts("0"); // Not a prime
|
|||
else |
|||
puts("1"); // Is a prime
|
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
EXECUTABLE=a.out |
|||
CC=g++ |
|||
CFLAGS=-g -lm -O2 -std=gnu++17 -Wall -Wextra |
|||
OBJ=main.cpp |
|||
|
|||
$(EXECUTABLE): $(OBJ) |
|||
$(CC) $(CFLAGS) -o $@ -static $(OBJ) |
|||
|
|||
.PHONY: clean |
|||
clean: |
|||
rm -rf $(EXECUTABLE) |
|||
|
|||
@ -0,0 +1,5 @@ |
|||
10 4 |
|||
? 1 3 |
|||
= 1 8 |
|||
= 3 8 |
|||
? 1 3 |
|||
@ -0,0 +1,9 @@ |
|||
4 8 |
|||
? 0 0 |
|||
= 0 1 |
|||
= 1 2 |
|||
= 0 2 |
|||
? 0 3 |
|||
? 0 1 |
|||
? 0 2 |
|||
? 1 2 |
|||
@ -0,0 +1,5 @@ |
|||
10 4 |
|||
= 1 2 |
|||
= 2 3 |
|||
= 2 4 |
|||
? 1 3 |
|||
@ -0,0 +1,6 @@ |
|||
4 5 |
|||
? 0 0 |
|||
= 0 1 |
|||
= 1 2 |
|||
= 0 2 |
|||
? 0 3 |
|||
@ -0,0 +1,106 @@ |
|||
/*
|
|||
* Author: André Palmborg |
|||
* |
|||
* Course: TDDD95 |
|||
* Task: 1.4: Unionfind |
|||
*/ |
|||
|
|||
|
|||
#include <stdio.h> /* scanf, printf, puts */
|
|||
#include <stdlib.h> /* malloc, free */
|
|||
|
|||
|
|||
/* DisjunctSets
|
|||
* |
|||
* unsigned N : Total number of elements. |
|||
* unsigned* nodes : Array keeping track of an elements parent in its set. |
|||
* The root elements parent is: (unsigned)(-1). |
|||
* |
|||
* Datastructure that keeps track of a set number of elements and the set they |
|||
* belong to. |
|||
* An element can only belong to one set at a time. |
|||
* Joining two elements together joins the two sets they belong to into one set. |
|||
* |
|||
*/ |
|||
struct DisjunctSets |
|||
{ |
|||
unsigned N; |
|||
unsigned* nodes; |
|||
|
|||
// Constructor initializes all elements so that they belong to the set
|
|||
// containing only themselves.
|
|||
DisjunctSets(unsigned _N) : N(_N) |
|||
{ |
|||
nodes = (unsigned*) malloc(N * sizeof(unsigned)); |
|||
for (unsigned i = 0; i < N; i++) |
|||
{ |
|||
nodes[i] = (unsigned)(-1); |
|||
} |
|||
} |
|||
~DisjunctSets() { free(nodes); } |
|||
|
|||
// Returns the root element of a set.
|
|||
// Side effects: Compresses the route to the root element by setting the
|
|||
// parent of all elements accessed while seeking the root
|
|||
// element to the root.
|
|||
unsigned get_root(unsigned n) |
|||
{ |
|||
// If checking the root element -> return root
|
|||
if (nodes[n] == (unsigned)(-1)) |
|||
return n; |
|||
else |
|||
{ |
|||
unsigned it = get_root(nodes[n]); |
|||
nodes[n] = it; |
|||
return it; |
|||
} |
|||
} |
|||
|
|||
// Returns true iff two elements are in the same set.
|
|||
bool query_same(unsigned a, unsigned b) |
|||
{ |
|||
if (a == b) |
|||
return true; |
|||
else |
|||
return (get_root(a) == get_root(b)); |
|||
} |
|||
|
|||
// Places two elements and the elements in their respective sets in the same set.
|
|||
void join_sets(unsigned a, unsigned b) |
|||
{ |
|||
unsigned a_root = get_root(a); |
|||
unsigned b_root = get_root(b); |
|||
if (a_root != b_root) |
|||
nodes[b_root] = a_root; |
|||
} |
|||
}; |
|||
|
|||
|
|||
int main() |
|||
{ |
|||
unsigned N, Q; |
|||
scanf("%d ", &N); // Get number of elements.
|
|||
scanf("%d ", &Q); // Get number of operations to be executed on the sets.
|
|||
DisjunctSets set(N); |
|||
|
|||
char op; |
|||
unsigned a, b; |
|||
bool same; |
|||
for (unsigned i = 0; i < Q; i++) |
|||
{ |
|||
scanf("%c %d %d ", &op, &a, &b); // Get operation type and arguments
|
|||
//scanf("%d ", &a); // Get arguments
|
|||
//scanf("%d ", &b); // -||-
|
|||
switch (op) |
|||
{ |
|||
case '?': same = set.query_same(a, b); |
|||
(same) ? puts("yes") : puts("no"); |
|||
break; |
|||
case '=': set.join_sets(a, b); |
|||
break; |
|||
default: throw "Bad argument"; |
|||
} |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue