This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
1 | 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
Duta Wacana Christian University
Cheat Sheet 2015
Icpc Asia Regional – Jakarta
PedWaY
Yosia – Wawan – Pedro
Contents Union Find ............................................................................................................. 3
Fenwick Tree ........................................................................................................ 3
Depth First Search ........................................................................................... 3
Breadth First Search ....................................................................................... 3
3 | 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
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; } };
Defense (Longest Increasing Subsequence) int main(){ int tc; int line = 0; string s; cin >> tc; //untuk mengabaikan input blank line getchar(); getline(cin, s); while(tc--){ if(line != 0) cout << endl; line = 1; vector<int> height; while(getline(cin, s)){
6 | 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(s.size() == 0) break; height.push_back(atoi(s.c_str())); } //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; }
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; }
Luggage (Dynamic Programming) int dp[21][201]; int suits[21]; int total, n; int knapsack(int suit, int take){ if(dp[suit][take] != -1) return dp[suit][take];
8 | 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
//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)); }
typedef vector<int> vi; #define LSOne(S) (S & (-S)) 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; } }; 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; }
Square (Dynamic Programming)
int memo[10005]; int dp(int n){ if(memo[n] != -1) return memo[n]; if(n <= 0) return 0; int minimum = 10010; for(int i = 1; i*i <= n; i++){ minimum = min(minimum, dp(n-i*i)+1); } return memo[n] = minimum; } int main(){ memset(memo, -1, sizeof (memo)); int tc, n; scanf("%d", &tc); while(tc--){ scanf("%d", &n); printf("%d\n", dp(n)); } return 0; }
A Node To Far 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());
map<int, int> name; v = 0; for(int i = 0; i < e; i++){ cin >> a >> b; if(name.find(a) == name.end()) name[a] = v++; if(name.find(b) == name.end()) name[b] = v++; AdjList[name[a]].push_back(ii(name[b], 0)); AdjList[name[b]].push_back(ii(name[a], 0)); } while(cin >> start >> ttl, start||ttl){ //if(start == 0 && ttl == 0) break; int s = name[start]; queue<int> q; q.push(s); map<int, int> dist; dist[s] = 0; reach = 1; while(!q.empty()){ s = q.front(); q.pop(); for(int i = 0; i < (int)AdjList[s].size(); i++){ ii d = AdjList[s][i]; if(dist.find(d.first) == dist.end()){ dist[d.first] = dist[s] + 1; if(dist[d.first] > ttl){ break; } q.push(d.first); reach++; } } } cout << "Case " << cases++ << ": " << v - reach << " nodes not reacheable from node " << start << " with TTL = " << ttl << ".\n"; } } return 0; }
Come And Go (Kosaraju) typedef pair<int, int> ii; typedef vector<int> vi; typedef vector<ii> vii; #define DFS_WHITE -1 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
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); } int main() { while (scanf("%d %d", &N, &M), (N || M)) { AdjList.assign(N, vii()); AdjListT.assign(N, vii()); for (i = 0; i < M; i++) { scanf("%d %d %d", &V, &W, &P); //agar berubah jadi index, dikurangi 1 V--; W--; //karena unweighted, semua weight 1 AdjList[V].push_back(ii(W, 1)); AdjListT[W].push_back(ii(V, 1)); if (P == 2) { AdjList[W].push_back(ii(V, 1)); AdjListT[V].push_back(ii(W, 1)); } } //S adalah vector yang berfungsi sebagai stack penampung post order S.clear(); // first pass dfs_num.assign(N, DFS_WHITE); for (i = 0; i < N; i++) if (dfs_num[i] == DFS_WHITE) Kosaraju(i, 1); numSCC = 0; // second pass dfs_num.assign(N, DFS_WHITE); //perulangan harus dari belakang agar sesuai reverse post order for (i = N-1; i >= 0; i--) if (dfs_num[S[i]] == DFS_WHITE) { numSCC++; Kosaraju(S[i], 2); } printf("%d\n", numSCC == 1 ? 1 : 0); } return 0; }
#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} };
// Print the solution floydWarshell(graph); return 0; }
Java Big Integer import java.math.BigInteger; import java.util.Scanner; publicclass JavaBigInteger { publicstaticvoid main(String args[]) { Scanner sc = new Scanner(System.in); BigInteger V = sc.nextBigInteger(); BigInteger sum = BigInteger.ZERO; sum = sum.add(V); int b = sc.nextInt(); // bigInteger base of b BigInteger p = new BigInteger(sc.next(), b); BigInteger m = new BigInteger(sc.next(), b); p.mod(m).toString(b);
// konversi int > BI BigInteger bI = BigInteger.valueOf(b); bI.isProbablePrime(10); // 10 is certainty p.gcd(m); //gcd of p and m // modulo arithmatic x ^ y mod n BigInteger x = BigInteger.valueOf(sc.nextInt()); BigInteger y = BigInteger.valueOf(sc.nextInt()); BigInteger n = BigInteger.valueOf(sc.nextInt()); x.modPow(y, n); } }
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
Count Number 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 *= (power+1); PF = primes[++PF_idx]; } if(N!=1) ans *= 2; returnans; }
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
Extended Euler Phi for(int i = 1; i <= 1000000; i++) EulerPhi[i] = i; for(int i = 2; i <= 1000000; i++) if(EulerPhi[i] == i) // i is prime for(int j = i; j <= 1000000; j += i) EulerPhi[j] = EulerPhi[j]/i * (i-1);
EXTENDED EULCID FOR ax + by = c int x0, y0, d; void extendedEuclid(int a, int b) { if ( b==0 ) { x = 1; y = 0; d = a; return; } extendedEuclid(b, a%b); int x1 = y; int y1 = x - (a/b) * y; x0 = x1; y0 = y1; } // ax + by = c, use d = gcd(a,b) | c to proof the validity // (x0, y0) found by extendedEuclid // x = x0 + (b/d) n, y = y0 + (a/d) n // thus, find n that completes the ax + by = c GCD int gcd(int a, int b){ return b == 0 ? a: gcd(b,a%b); } int lcm(int a, int b){ return a * (b / gcd(a,b)); } // Find the gcd(p,q) and x,y such that p*x + q*y = gcd(p,q) long gcd(long p, long q, long *x, long *y)
{ long x1,y1; /* previous coefficients */ long g; /* 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); }
UVA 10036 – Divisibility #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;} int mod(int x,int y){return ((x%y)+y)%y;} int dp(int num,int i) { if(i==n) { if(mod(num,k)==0) return 1; else return 0; } if(memo[mod(num,k)][i] != -1) return memo[mod(num,k)][i]; return memo[mod(num,k)][i] = max(dp(num-in[i],i+1), dp(num+in[i],i+1) ); } int main()
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)
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 power=2 x=1 1 2 2 // power = power ^ 2 mod 123 0 4 2 // if 0 keep x, if 1 x = x * power mod 123 1 16 32 0 10 32 1 100 2 1 37 74 The (slightly cryptic) output of this program can be read as:
1. The base two digits of the exponent 2. The successive squarings of the base (ie b2, b4, b8, ...) 3. The product of the appropriate squares
Fibonacci Number fib(n) = ( o^n – (-o)^-n ) / sqrt(5); // o = (1+sqrt(5)/2) // test n first, some n may results incorrectly
Floyd Cycle Finding Algorithm THEORY f(x) = ( Z.x+I)%M with x0 = L ex: Z = 7, I = 5, M = 12, L = 4 so: f(x) = ( 7x+5)%12, x0 = 4 { 4, 9, 8, 1, 0, 5, 4, 9, 8, 1, 0, 5, … } cycle length = 6 start of cycle = 0 // function int f(x) is defined earlier ii floydCycleFinding(int x0){
// 1st part: find k * mu, hare’s speed 2x tortoise’s int tortoise = f(x0), hare = f(f(x0)); // f(x0) node next to x0 while(tortoise != hare) { tortoise = f(tortoise); hare = f(f(hare)); } // 2nd part: finding mu, hare and tortoise move at the same speed int mu = 0; hare = x0; while(tortoise != hare){
tortoise = f(tortoise); hare = f(hare); mu++; } // 3rd part: finding lambda, hare moves, tortoise stays int lamba = 1; hare = f(tortoise); while(tortoise != hare) { hare = f(hare); lamba++; } return ii(mu, lamba);