Beruflich Dokumente
Kultur Dokumente
Genes ........................................................................................................................ 7
PedWaY
Contents
Union Find ............................................................................................................. 3
Fenwick Tree ........................................................................................................ 3
Depth First Search ........................................................................................... 3
Breadth First Search ....................................................................................... 3
Shortest Path (Dijkstra) .............................................................................. 3
Bellman Ford ........................................................................................................ 3
Topological Sort ................................................................................................ 3
Kosaraju ................................................................................................................. 4
Tarjan...................................................................................................................... 4
Kruskal ................................................................................................................... 4
Longest Increasing / Decreasing Subsequence .................................... 4
GCD & LCM ............................................................................................................... 4
Library & Others ................................................................................................ 5
Bytelandian Coins (Dynamic Programming) ............................................. 5
Defense (Longest Increasing Subsequence) ........................................... 5
Freckles ................................................................................................................. 6
Union Find
class UnionFind {
private:
vi p, rank, setSize;
int numSets;
public:
UnionFind(int N) {
setSize.assign(N, 1); numSets = N; rank.assign(N, 0);
p.assign(N, 0); for (int i = 0; i < N; i++) p[i] = i; }
int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
void unionSet(int i, int j) {
if (!isSameSet(i, j)) { numSets--;
int x = findSet(i), y = findSet(j);
if (rank[x] > rank[y]) { p[y] = x; setSize[x] += setSize[y]; }
else
{ p[x] = y; setSize[y] += setSize[x];
if (rank[x] == rank[y]) rank[y]++; } } }
int numDisjointSets() { return numSets; }
int sizeOfSet(int i) { return setSize[findSet(i)]; }
};
Fenwick Tree
class FenwickTree{
private:
vi ft;
public:
FenwickTree(int n) { ft.assign(n+1, 0); }
int rsq(int b) { int sum=0; for(; b; b -= LSOne(b)) sum += ft[b]; return sum; }
int rsq(int a, int b) { return rsq(b) (a == 1 ? 0 : rsq(a-1)); }
void adjust(int k, int v) { for(; k<(int)ft.size(); k+=LSOne(k)) ft[k]+=v; } };
while(!q.empty()) {
int u=q.front(); q.pop();
for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v=AdjList[u][j];
if(d[v.first] == INF) { d[v.first] = d[u] + 1; q.push(v.first); } } }
Bellman Ford
int s = 1;
vi dist(N+1, INF); dist[s]=0;
for(int i = 1; i < N; i++) for(int u = 1; u < N+1; u++)
for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v = AdjList[u][j];
dist[v.first] = min(dist[v.first], dist[u] + v.second); }
bool hasNegativeCycle = false;
for(int u = 1; u < N+1; u++)
for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v = AdjList[u][j]; if(dist[v.first] > dist[u] + v.second)
hasNegativeCycle = true; } printf();
Topological Sort
vi ts;
void dfs2(int u){
dfs_num[u] = VISITED;
for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v = AdjList[u][j];
if(dfs_num[v.first] == UNVISITED)
dfs2(v.first);
}
ts.push_back(u);
}
----------------------------------------------------------------------------------int i, j, N, M, V, W, P, dfsNumberCounter, numSCC;
vector<vii> AdjList, AdjListT;
vi dfs_num, dfs_low, S, S_copy, visited;
Kruskal
vector< pair<int, ii> > EdgeList;
sort(EdgeList.begin(), EdgeList.end());
mstnew=0; UnionFind UF(N);
for(int I = 0; i < M+K; i++) {
pair<int, ii> nextEdge = EdgeList[i];
if(!UF.isSameSet(nextEdge.second.first, nextEdge.second.second)) {
mstnew += nextEdg.1st;
UF.unionSet(nextEdge.second.first, nextEdge.second.first); } }
-----------------------------------------------------------------------------------
Kosaraju
void Kosaraju(int u, int pass) {
dfs_num[u] = 1; vii neighbor;
if(pass==1) neighbor = AdjList[u];
else neighbor = AdjListT[u];
for(int j = 0; j < (int)neighbor.size(); j++) {
ii v = neighbor[j];
if(dfs_num[v.first] == DFS_WHITE) Kosaraju(v.first, pass);
}
S.push_back(u); }
void doLIS() {
LIS[0] = 1;
for(int i = n - 1; i >= 0; i--){ ul tmp = 1; for(int j = i + 1; j < n; j++) {
if(v[i] < v[j]){ tmp = max(tmp, LIS[j] + 1); } } LIS[i] = tmp; } }
void doLDS() {
LDS[0] = 1;
for(int i = n - 1; i >= 0; i--){ ul tmp = 1; for(int j = i + 1; j < n; j++) {
if(v[i] > v[j]){ tmp = max(tmp, LDS[j] + 1); } } LDS[i] = tmp; } }
<vector>
<list>
<map>
<set>
<queue>
<deque>
<stack>
<bitset>
<algorithm>
<functional>
<numeric>
<utility>
<sstream>
<iostream>
<iomanip>
<cstdio>
<cmath>
<cstdlib>
<ctime>
<cstring>
<string>
if(s.size() == 0) break;
height.push_back(atoi(s.c_str()));
}
while(!urutan.empty()){
printf("%d\n", urutan.top());
urutan.pop();
}
}
//hitung jumlah input
int n = height.size();
//jika tidak ada input
if(n == 0){
printf("Max hits: 0\n");
continue;
}
//bagian dynamic programming-nya
//bisa dijadikan fungsi
vector<int> lis;
lis.push_back(1);
for(int i = 1; i < n; i++){
//nilai lis untuk nilai yang terkecil dari 0 s/d i adalah 1
int temp = 1;
//cek nilai sebelumnya
for(int j = i-1; j >= 0; j--){
//jika nilai sebelumnya lebih besar dari nilai ke i
if(height[i] > height[j]){
//ubah nilai lis
temp = max(temp, lis[j]+1);
}
}
//setelah dapat yang maksimal, tampung hasilnya
lis.push_back(temp);
}
//akhir bagian dynamic programming-nya
int max = 0;
int index = 0;
//mencari nilai lis maksimum dan indeksnya
for(int i = 0; i < n; i++){
if(lis[i] > max){
max = lis[i];
index = i;
}
}
printf("Max hits: %d\n", max);
stack<int> urutan;
urutan.push(height[index]);
max--;
for(int i = index-1; i >= 0; i--){
if(lis[i] == max){
urutan.push(height[i]);
max--;
if(max == 0) break;
}
}
// cin >> tc;
return 0;
}
Freckles
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef pair<double, double> dd;
const int INF = 999999999;
// Union Find Class
int main(){
int tc, point;
double x, y, mst_cost;
vector<dd> v;
vector<pair<double, ii> > EdgeList;
string buang;
scanf("%d", &tc);
while(tc--){
v.clear();
EdgeList.clear();
mst_cost = 0;
getline(cin, buang);
getline(cin, buang);
scanf("%d", &point);
while(point--){
cin >> x >> y;
v.push_back(dd(x, y));
}
for(int i = 0; i < v.size(); i++){
for(int j = i+1; j < v.size(); j++){
double w = sqrt((v[i].firstv[j].first)*(v[i].first-v[j].first) + (v[i].second-v[j].second)*(v[i].secondv[j].second));
EdgeList.push_back(make_pair(w, ii(i+1, j+1)));
}
}
sort(EdgeList.begin(), EdgeList.end());
UnionFind UF(v.size());
for(int i = 0; i < EdgeList.size(); i++){
pair<double, ii> front = EdgeList[i];
if(!UF.isSameSet(front.second.first, front.second.second)){
mst_cost += front.first;
UF.unionSet(front.second.first,
front.second.second);
}
}
printf("%.2f\n", mst_cost);
} }
Genes
typedef pair<string, string> ss;
map<string, string> gen;
map<string, ss> parent;
set<string> name;
set<string> childlist;
set<string>::iterator iterset;
string findParent(string child){
if(gen[child] != "") return gen[child];
string p1 = findParent(parent[child].first);
string p2 = findParent(parent[child].second);
if(p1 == "dominant" && p2 == "dominant") return "dominant";
if(p1 == "dominant" && p2 == "recessive") return "dominant";
if(p1 == "dominant" && p2 == "non-existent") return "recessive";
if(p1 == "recessive" && p2 == "dominant") return "dominant";
if(p1 == "recessive" && p2 == "recessive") return "recessive";
if(p1 == "recessive" && p2 == "non-existent") return "non-existent";
if(p1 == "non-existent" && p2 == "dominant") return "recessive";
if(p1 == "non-existent" && p2 == "recessive") return "non-existent";
if(p1 == "non-existent" && p2 == "non-existent") return "non-existent";
}
int main(){
int line;
string str1, str2;
cin >> line;
while(line--){
cin >> str1 >> str2;
if(str2 == "dominant" || str2 == "recessive" || str2 == "non-existent"){
gen[str1] = str2;
name.insert(str1);
}
else{
if(parent[str2].first == "") parent[str2].first = str1;
else parent[str2].second = str1;
childlist.insert(str2);
name.insert(str2);
}
}
iterset = childlist.begin();
for( ; iterset != childlist.end(); iterset++){
gen[*iterset] = findParent(*iterset);
}
iterset = name.begin();
for( ; iterset != name.end(); iterset++){
cout << *iterset << " " << gen[*iterset] << endl;
}
return 0; }
Large KnapSack
using namespace std;
int dp[2][2000001] = {0};
int main(){
int k, n, v[505], w[505], index, prev;
scanf("%d %d", &k, &n);
for(int i = 1; i <= n; i++){
scanf("%d %d", &v[i], &w[i]);
}
for(int i = 1; i <= n; i++){
index = i % 2;
prev = (i - 1) % 2;
for(int j = 0; j <= k; j++){
if(j >= w[i]){
dp[index][j] = max(dp[prev][j], v[i] + dp[prev][j-w[i]]);
}
else dp[index][j] = dp[prev][j];
}
/* for(int j = 0; j <= k; j++) printf("%d ", dp[0][j]);
printf("\n");
for(int j = 0; j <= k; j++) printf("%d ", dp[1][j]);
printf("\n");
system("pause"); */
}
printf("%d\n", dp[n%2][k]);
return 0;
}
//kalau jumlah suit = jumlah semua suit, return selisih antara take dan ignore
(ignore = total - take)
//abs(take - (total - take) = abs(take - total + take) = abs(2*take - total)
if(suit == n - 1) return dp[suit][take] = abs(total - 2*take);
//recursive case
return dp[suit][take] = min(knapsack(suit+1, take+suits[suit]), knapsack(suit+1,
take));
}
Luggage (Cont.)
int main(){
int tc, suit, half, flag;
string input;
cin >> tc;
getline(cin, input);
while(tc--){
memset(dp, -1, sizeof(dp));
total = 0;
n = 0;
getline(cin, input);
istringstream iss(input);
while(iss >> suits[n]){
total += suits[n];
n++;
}
if(total % 2 == 1){
cout << "NO" << endl;
continue;
}
if(knapsack(0,0) == 0) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
getline(cin, input);
while(tc--){
vector<int> v;
total = 0;
getline(cin, input);
istringstream iss(input);
while(iss >> suit){
v.push_back(suit);
total += suit;
}
if(total % 2 == 1){
cout << "NO" << endl;
continue;
}
size = v.size();
possibility = pow(2, size);
sort(v.begin(), v.end());
half = total / 2;
// jika koper terberat lebih besar half, langsung "NO"
if(v[size-1] > half){
cout << "NO" << endl;
continue;
}
// jika koper terberat sama dengan half, langsung "YES"
if(v[size-1] == half){
cout << "YES" << endl;
continue;
}
// jika koper terberat lebih kecil half tapi ditambah koper
terkecil jadi
// lebih besar half, langsung "NO"
if(v[size-1] + v[0] > half){
cout << "NO" << endl;
continue;
}
// array tidak hanya di-set menjadi half semua, tapi langsung
mempertimbangkan koper terberat
// setengah depan untuk "jika tidak ambil"
for(int i = 0; i <= possibility/2; i++) bruteforce[i] = half;
// setengah belakang untuk "jika ambil"
half -= v[size-1];
for(int i = possibility/2; i < possibility; i++) bruteforce[i] =
half;
/* untuk lihat isi array setelah ambil koper terberat *
for(int j = 0; j < possibility; j++) cout << bruteforce[j] << " ";
cout << endl;
//*/
part = pow(2, size-2);
flag = 0;
Median (Priority_Queue)
int main(){
int in, size = 0;
priority_queue<int> maxpq;
priority_queue<int, vector<int>, greater<int> > minpq;
scanf("%d", &in);
maxpq.push(in);
size++;
printf("%d\n", in);
while(scanf("%d", &in) == 1){
maxpq.push(in);
size++;
if(size % 2 == 0){
minpq.push(maxpq.top());
maxpq.pop();
}
+ 1, 0); }
+= ft[b];
: rsq(a - 1));
+= LSOne(k)) ft[k] += v;
int main(){
int N, add, x, y, r, cases = 0;
char command[10];
while(scanf("%d", &N) && (N!=0)){
FenwickTree ft(N);
if(cases != 0) printf("\n");
printf("Case %d:\n", ++cases);
for(int i = 1; i <= N; i++){
scanf("%d", &add);
ft.adjust(i, add);
}
while(scanf("%s", &command) && !((command[0] == 'E') && (command[1] == 'N')
&& (command[2] == 'D'))){
10 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
if(command[0] == 'S'){
cin >> x >> r;
int old = ft.rsq(x, x);
ft.adjust(x, r-old);
}
else if(command[0] == 'M'){
cin >> x >> y;
printf("%d\n", ft.rsq(x, y));
}
}
}
return 0; }
cout << "Case " << cases++ << ": " << v - reach << " nodes
not reacheable from node "
<< start << " with TTL = " << ttl << ".\n";
}
}
return 0;
}
A Node To Far
Come And Go (Kosaraju)
typedef pair<int, int> ii;
typedef vector<ii> vii;
int main(){
int maxv = 30, e, a, b, v, start, ttl, reach, cases = 1;
vector<vii> AdjList;
while(cin >> e, e){
AdjList.clear();
AdjList.assign(maxv, vii());
typedef
typedef
typedef
#define
int i, j, N, M, V, W, P, numSCC;
vector<vii> AdjList, AdjListT;
vi dfs_num, S;
11 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
vector<int> sequence;
while(cin >> in){
if(in == -999999){
maxstreak = -999999;
for(int i = 0; i < sequence.size(); i++){
streak = 1;
for(int j = i; j < sequence.size(); j++){
if(sequence[j] == 0){
streak = 1;
if(maxstreak < 0) maxstreak = 0;
} else {
streak *= sequence[j];
if(streak > maxstreak) maxstreak = streak;
}
}
}
printf("%lld\n", maxstreak);
sequence.clear();
} else {
sequence.push_back(in);
}
}
return 0;
12 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
postn >>= 1;
while(postn > 0){
tree[postn].merge(tree[postn*2], tree[postn*2+1]);
postn >>= 1;
}
Node n;
n.segmentSum = n.bestPrefix = n.bestSuffix = n.bestSum = val;
return n;
}
}
void update(int post, Node new_val){
pos += (1 << n);
tree[pos] = new_val;
mergeup(pos);
}
Orderset
Segment Tree (Contoh GSS3)
//range_query and update function remain same as that for last problem
struct Node{
int segmentSum, bestPrefix, bestSuffix, bestSum;
Node split(Node& l, Node& r){}
Node merge(Node& l, Node& r){
segmentSum = l.segmentSum + r.segmentSum;
bestPrefix = max(l.segmentSum + r.bestPrefix, l.bestPrefix);
bestSuffix = max(r.segmentSum + l.bestSuffix, r.bestSuffix);
bestSum
= max(max(l.bestSum, r.bestSum), l.bestSuffix + r.bestPrefix);
}
};
Node createLeaf(int val){
struct Node{
int num_active_leaves;
void split(Node& l, Node& r){}
void merge(Node& l, Node& r){
num_active_leaves = l.num_active_leaves + r.num_active_leaves;
}
bool operator < (const Node& n) const{
return num_active_leaves < n.num_active_leaves;
}
};
int binary_search(Node k){
int root = l;
Node n = identity;
assert(!(k<identity));
while(!isleaf(root)){
13 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
General Merge Up
void splitdown(int postn){
if(postn > 1) splitdown(postn >> 1);
tree[postn].split(tree[2 * postn], tree[2 * postn + 1]);
}
void update(int postn, Node nd){
postn += 1 << n;
splitdown(postn >> 1);
tree[postn] = nd;
mergeup(postn);
}
tree[root].lazy = 0;
tree[root].leaves = 1;
return tree[root];
}
Node l = build(left(root), L, (L+R)/2);
Node r = build(right(root), (L+R)/2+1, R);
tree[root].merge(l, r);
return tree[root];
}
void update_single_subtree(Node& n, ll inc){
n.lazy += inc;
n.sum += inc * n.leaves;
}
void update(ll root, ll L, ll R, ll i, ll j, ll val){
if(L > j || R < i){
return;
}
if(L >= i && R <= j){
return update_single_subtree(tree[root], val);
}
tree[root].split(tree[left(root)], tree[right(root)]);
update(left(root), L, (L+R)/2, i, j, val);
update(right(root), (L+R)/2+1, R, i, j, val);
tree[root].merge(tree[left(root)], tree[right(root)]);
}
Node query(int root, int L, int R, int i, int j){
if(L > R || L > j || R < i) return dummy;
if(L >= i && R <= j){
return tree[root];
}
tree[root].split(tree[left(root)], tree[right(root)]);
Node l = dummy, r = dummy;
l = query(left(root), L, (L+R)/2, i, j);
r = query(right(root), (L+R)/2+1, R, i, j);
tree[root].merge(tree[left(root)], tree[right(root)]);
Node res;
res.merge(l,r);
return res;
}
int main(){
dummy.sum = dummy.lazy = dummy.leaves = 0;
ll tc;
ll n, c, cmd, p, q, v;
cin >> tc;
while(tc--){
cin >> n >> c;
build(1, 0, n-1);
REP(i, c){
cin >> cmd;
if(cmd == 1){
cin >> p >> q;
cout << query(1, 0, n-1, --p, --q).sum << endl;
14 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
}
else{
cin >> p >> q >> v;
update(1, 0, n-1, --p, --q, v);
}
}
}
}
}
for(int i=0; i<n; i++){
int cost, subj;
string input;
getline(cin, input);
if(input.size() == 0) getline(cin, input);
istringstream is; is.str(input);
is >> cost; teacherCost[i] = cost;
DP Bitmask
int
int
int
int
int
s, n, m;
dp[110][110][8];
teacherCost[110];
teacherMask[110];
go(int slot1, int slot2, int i){
if(slot1 == (i << s) -1 && slot2 == (i << s) - 1){
return 0;
}
else if(i >= n){
return 1000000000;
}
else if(dp[slot1][slot2][i] != -1){
return dp[slot1][slot2][i];
}
else{
return dp[slot1][slot2][i] = min(go(slot1, slot2, i+1), teacherCost[i] +
go(slot1 | teacherMask[i], slot2 | (slot1 & teacherMask[i]), i+1));
}
}
int main(){
while(cin >> s >> m >> n){
if(!s) break;
for(int i=0; i<(1 << s); i++){
for(int j=0; j<(1 << s); j++){
for(int k=0; k<n; k++){
dp[i][j][k] = -1;
}
}
}
int slot1 = 0, slot2 = 0;
int subMask = 0;
int totalCost = 0;
for(int i=0; i<m; i++){
Sieve Of Erastothenes
int main()
{
bool is_prime;
uInt count = 1;
uInt my_prime = 2; //set to first prime
for(uInt i = 3; count < 10001; i += 2) { //skip ALL even numbers, find
10001st prime
is_prime = true;
for(uInt j = 3; j * j <= i && is_prime; j += 2) //again, skipping
all even numbers
if(i % j == 0) is_prime = false;
15 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
if(is_prime) {
++count;
my_prime = i;
}
}
cout << my_prime;
//cin.get();
}
Floyd Warshall
#include<stdio.h>
// Number of vertices in the graph
#define V 4
/* Define Infinite as a large enough value. This value will be used
for vertices not connected to each other */
#define INF 99999
// A function to print the solution matrix
void printSolution(int dist[][V]);
// Solves the all-pairs shortest path problem using Floyd Warshall algorithm
void floydWarshell (int graph[][V])
{
/* dist[][] will be the output matrix that will finally have the shortest
distances between every pair of vertices */
int dist[V][V], i, j, k;
/* Initialize the solution matrix same as input graph matrix. Or
we can say the initial values of shortest distances are based
on shortest paths considering no intermediate vertex. */
for (i = 0; i < V; i++)
for (j = 0; j < V; j++)
dist[i][j] = graph[i][j];
/* Add all vertices one by one to the set of intermediate vertices.
---> Before start of a iteration, we have shortest distances between all
pairs of vertices such that the shortest distances consider only the
vertices in set {0, 1, 2, .. k-1} as intermediate vertices.
----> After the end of a iteration, vertex no. k is added to the set of
intermediate vertices and the set becomes {0, 1, 2, .. k} */
for (k = 0; k < V; k++)
{
// Pick all vertices as source one by one
for (i = 0; i < V; i++)
16 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
{
// Pick all vertices as destination for the
// above picked source
for (j = 0; j < V; j++)
{
// If vertex k is on the shortest path from
// i to j, then update the value of dist[i][j]
if (dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
// Print the shortest distance matrix
printSolution(dist);
}
/* A utility function to print solution */
void printSolution(int dist[][V])
{
printf ("Following matrix shows the shortest distances"
" between every pair of vertices \n");
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (dist[i][j] == INF)
printf("%7s", "INF");
else
printf ("%7d", dist[i][j]);
}
printf("\n");
}
}
// driver program to test above function
int main()
{
/* Let us create the following weighted graph
10
(0)------->(3)
|
/|\
5 |
|
|
| 1
\|/
|
(1)------->(2)
3
*/
int graph[V][V] = { {0,
5, INF, 10},
{INF, 0,
3, INF},
{INF, INF, 0,
1},
{INF, INF, INF, 0}
};
17 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
vi primeFactors(ll N)
{
vi factors;
ll PF_idx = 0, PF = primes[PF_idx];
while(PF*PF <= N)
{
while(N%PF == 0) {N /= PF; factors.push_back(PF);}
PF = primes[++PF_idx];
}
if(N!=1) factors.push_back(N);
return factors;
}
Prime Factor
Sum Divisors
vi numDiv(ll N)
{
ll PF_idx = 0, PF = primes[PF_idx], ans = 1;
while(PF*PF <= N)
{
ll power = 0;
while(N%PF == 0) {N /= PF; power++;}
ans *= ((ll)pow((double)PF, power+1.0)-1)/(PF-1);
PF = primes[++PF_idx];
}
if(N!=1) ans *= ((ll)pow((double)PF, 2.0)-1)/(N-1);
returnans;
18 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
Catalan Number
Cat(n) = (2n C n) / (n+1)
Cat(0) = 1
Cat(n+1) = (2n+2)(2n+1)/(n+2)(n+1) x Cat(n)
Ex: n = 3, Cat(3) = 5
distinct binary tress vertices of 3
/br/, /br\, /\, \br/, \br\
19 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
Euler Phi
ll EulerPhi(ll N)
{
ll PF_idx = 0, PF = primes[PF_idx], ans = N;
while(PF*PF <= N)
{
if (N % PF == 0) ans -= ans / PF;
while(N%PF == 0) N /= PF;
PF = primes[++PF_idx];
}
if(N!=1) ans -= ans / N;
return factors;
}
// find different x, x < N, x is relatively prime with N
// 36 = 3^2 * 2^2
// there is 36 * (1-1/2) (1-1/3) = 12 different x
// {1, 3, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35}
// if N is prime , { 1 ... N-1 } is relatively prime
{
long x1,y1;
long g;
/* previous coefficients */
/* value of gcd(p,q) */
if (q > p) return(gcd(q,p,y,x));
if (q == 0) {
*x = 1;
*y = 0;
return(p);
}
g = gcd(q, p%q, &x1, &y1);
*x = y1;
*y = (x1 - floor(p/q)*y1);
return(g);
}
#include <stdio.h>
#include <cmath>
int n, k;
int in[10010];
int memo[110][10010];
int max(int a,int b){return (b>a) ? b:a;}
20 | D u t a W a c a n a C h r i s t i a n U n i v e r s i t y C h e a t S h e e t 2 0 1 5
{
int tc;
scanf("%d",&tc);
while(tc--)
{
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d",&in[i]);
if(in[i]%k == 0)
{
i--;
n--;
}
}
for(int i=0;i<110;i++)
for(int j=0;j<10010;j++)
memo[i][j]=-1;
int res = dp(0,0);
if(res!=0)
printf("Divisible\n");
else
printf("Not divisible\n");
}
return 0;
}
Exponentiation - The Russian Peasant Algorithm
When computing a power of a number with a finite modulus there are efficient ways to
do it and inefficient ways to do it. In this section we will outline a commonly used
efficient method which has the curious name "the Russian Peasant algorithm".
The most obvious way to compute 1210 (mod 23) is to multiply 12 a total of nine
times, reducing the result mod 23 at each step. A more efficient method which takes
only four multiplications is accomplished by first noting that:
122=6 (mod 23)
124=62=13 (mod 23)
128=132=8 (mod 23)
We have now performed three squarings and, by noting that the exponent breaks into
powers of 2 as 10=8+2, we can rewrite our computation:
1210=12(8+2)
=128*122
=8*6=2(mod 23)
So our algorithm consists of writing the exponent as powers of two. (This can be
done by writing it as a number base 2 and reading off successive digits - eg
1010=10102.) Now we multiply successive squares of the base number for each digit of
the exponent which is a "1".
The following short program will allow you to compute examples of the Russian
Peasant method for exponentiation:
2 ^ 53 mod 123 = 74
binary
1
0
1
0
1
1
power=2
2
4
16
10
100
37
x=1
2
2
32
32
2
74
Fibonacci Number
fib(n) = ( o^n (-o)^-n ) / sqrt(5);
// o = (1+sqrt(5)/2)
// test n first, some n may results incorrectly