├── Disjoint-Set-Union-Merge.cpp ├── README.md ├── Tarjan_SCC.cpp ├── Z Algorithm.cpp ├── ArticulationPoints.cpp ├── MaxBipartiteMatching.cpp ├── KMP.cpp ├── Manacher.cpp ├── LCA.cpp ├── rangeQuery.cpp ├── LIS(nlogn).cpp ├── FordFulkerson.cpp ├── Trie.cpp ├── template.cpp ├── EdmondsKarpMaxFlow.cpp ├── ConvexHullOptimization.cpp ├── Treap.cpp ├── DinicsFlow.cpp ├── SuffixAutomata.cpp ├── FFT.cpp ├── geometry.hpp ├── MinCostMaxFlow.cpp ├── SuffixArray.cpp ├── Palindrome Tree.cpp ├── segmentTree.cpp ├── implicitTreap.cpp ├── Formulae.tex └── BigIntClasses.cpp /Disjoint-Set-Union-Merge.cpp: -------------------------------------------------------------------------------- 1 | /* Disjoint Set Union Data Structure */ 2 | 3 | #define N 100100 4 | int _par[N]; 5 | 6 | struct DisjointSet 7 | { 8 | DisjointSet() 9 | { 10 | for(int i=0;i dfs_scc; 2 | bool in_stack[NN]; // set to 0 3 | int dfs_low[NN]; 4 | int dfs_num[NN]; 5 | int counter; // set to 0 before every call of this function 6 | bool scc_vis[NN]; // set to 0 7 | vector adl[NN]; 8 | 9 | 10 | // call while some node is not visited 11 | void tarjanSCC(int u) { 12 | dfs_low[u] = dfs_num[u] = counter++; scc_vis[u] = true; 13 | dfs_scc.push(u); in_stack[u] = true; 14 | for(int i = 0;i < adl[u].size();i++) { 15 | int v = adl[u][i]; 16 | if(!scc_vis[v]) 17 | tarjanSCC(v); 18 | if(in_stack[v]) 19 | dfs_low[u] = min(dfs_low[u], dfs_low[v]); 20 | } 21 | 22 | if(dfs_low[u] == dfs_num[u]) { 23 | // u is the root 24 | while(dfs_scc.size() && dfs_scc.top() != u) { 25 | in_stack[dfs_scc.top()] = 0; 26 | // Do your action here 27 | dfs_scc.pop(); 28 | } 29 | 30 | in_stack[u]=0; 31 | // Do action for the root here 32 | dfs_scc.pop(); 33 | } 34 | } -------------------------------------------------------------------------------- /Z Algorithm.cpp: -------------------------------------------------------------------------------- 1 | // z[i] gives the maximum length of substring starting from i which is a prefix 2 | // maintain l and r which gives the maximum prefix substring last found 3 | // if i > r start fresh 4 | // else compare with z[i - l] 5 | // if(z[i - l] < r - i + 1) z[i] = z[i - l] 6 | // else start fresh 7 | 8 | #define N 100100 9 | int z[N]; 10 | 11 | void calcZ(string s) { 12 | int n = (int)s.length(); 13 | z[0] = n; 14 | int l = 0, r = 0; 15 | for(int i = 1; i < n; i++) { 16 | if(i > r) { 17 | l = r = i; 18 | while(r < n && s[r - l] == s[r]) r++; 19 | z[i] = r - l; r--; 20 | } else { 21 | int k = i - l; 22 | if(z[k] < r - i + 1) z[i] = z[k]; 23 | else { 24 | l = i; 25 | while(r < n && s[r - l] == s[r]) r++; 26 | z[i] = r - l; r--; 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ArticulationPoints.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Articulation points, O(E+V) 3 | */ 4 | 5 | #define N 3010 6 | vector adl[N]; // Adjacency list 7 | int art[N],visited[N]; // initialize art and visited by 0 8 | int dn[N],parent[N]; // initialize parent to -1 9 | int timer, tin[N], fup[N]; // initialize timer to 0 10 | 11 | void dfsart(int v, int p = -1) { 12 | visited[v] = true; 13 | tin[v] = fup[v] = timer++; 14 | int children = 0; 15 | for (int i=0; i= tin[v] && p != -1) 24 | art[v] = 1; 25 | ++children; 26 | } 27 | } 28 | if (p == -1 && children > 1) 29 | art[v] = 1; 30 | } 31 | -------------------------------------------------------------------------------- /MaxBipartiteMatching.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Ford Fulkerson with finding augmenting paths using DFS. 3 | O((E+V)*V) (In practice, even faster) 4 | */ 5 | 6 | #define N 2020 7 | int s; // Number of nodes in a graph 8 | vector adj[N]; // Directed graph adjacency list 9 | int done[N]; 10 | int match[N]; 11 | 12 | bool trym(int a) 13 | { 14 | if(a < 0) return 0; 15 | for(int i = 0; i < adj[a].size(); i++) 16 | if(!done[adj[a][i]]) 17 | { 18 | done[adj[a][i]] = 1; 19 | if(match[adj[a][i]] == -1 || trym(match[adj[a][i]])) 20 | { 21 | match[adj[a][i]] = a; 22 | return 1; 23 | } 24 | } 25 | return 0; 26 | } 27 | 28 | int maxMatch() 29 | { 30 | mset(match,-1); 31 | count=0; 32 | for(int i = 0;i < s; i++) 33 | { 34 | mset(done,0); 35 | if(trym(i)) count++; 36 | } 37 | return count; 38 | } -------------------------------------------------------------------------------- /KMP.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | KMP string matching. O(n) 3 | */ 4 | 5 | #define NN 100100 6 | 7 | int F[NN]; 8 | 9 | void computeFailure(char T[], int m) { // m is the length of T 10 | int i = 1,j = 0; 11 | F[0] = 0; 12 | while(i < m) { 13 | while(j < m && T[i] == T[j]) { 14 | ++j; F[i] = j; ++i; 15 | } 16 | if(i == m) break; 17 | if(j == 0) { 18 | F[i] = 0; 19 | ++i; 20 | } else { 21 | j = F[j-1]; 22 | } 23 | } 24 | } 25 | 26 | int KMP(const string & S,char T[]) { // search T in S 27 | int n = S.length(); 28 | int m = strlen(T); 29 | int cnt = 0; 30 | if(m > n) return 0; 31 | computeFailure(T, m); 32 | int i = 0, j = 0; 33 | while((i-j) <= n - m) { 34 | while(j < m && S[i] == T[j]) { 35 | ++j; ++i; 36 | } 37 | if(j == m) cnt++; // match found 38 | if(j == 0) ++i; 39 | else j = F[j-1]; 40 | } 41 | return cnt; 42 | } -------------------------------------------------------------------------------- /Manacher.cpp: -------------------------------------------------------------------------------- 1 | // O(n) 2 | // length of odd palindrome centered at i = 2 * odd[i] + 1 3 | // length of even palindrome centered at i and i - 1 = 2 * even[i] 4 | 5 | #define N 100100 6 | int odd[N], even[N]; 7 | 8 | void manacher(string s) { 9 | int n = (int)s.length(); 10 | int l = 0, r = -1; 11 | 12 | // compute odd length palindromes centered at i 13 | for(int i = 0; i < n; i++) { 14 | int k = (i > r ? 0 : min(odd[l + r - i], r - i)) + 1; 15 | while(i + k < n && i - k >= 0 && s[i - k] == s[i + k]) k++; 16 | odd[i] = --k; 17 | if(i + k > r) l = i - k, r = i + k; 18 | } 19 | 20 | // compute even length palindromes centered at i and i - 1 21 | l = 0, r = -1; 22 | for(int i = 0; i < n; i++) { 23 | int k = (i > r ? 0 : min(even[l + r - i + 1], r - i + 1)) + 1; 24 | while(i + k - 1 < n && i - k >= 0 && s[i - k] == s[i + k - 1]) k++; 25 | even[i] = --k; 26 | if(i + k - 1 > r) l = i - k, r = i + k - 1; 27 | } 28 | } -------------------------------------------------------------------------------- /LCA.cpp: -------------------------------------------------------------------------------- 1 | // parent[i] is the just immediate ancestor of i 2 | // level[i] is the level (0, 1, 2, ...) in the tree 3 | // P[i][j] is the 2^j th ancestor of i 4 | // call init() for all x (nodes of the tree) 5 | // Preprocessing - O(nlogn) 6 | // lca(u, v) - O(logn) 7 | 8 | #define N 100100 9 | #define LG 20 10 | int parent[N], P[N][LG], level[N]; 11 | 12 | // Initialisation should be levelwise, 13 | // i.e all the parents of x must have been processed before x 14 | // We may run a dfs to do that 15 | 16 | inline void init(int x, int n) { 17 | for(int i = 0; i < LG; i++) P[x][i] = -1; 18 | P[x][0] = parent[x]; 19 | for(int j = 1; (1 << j) < n; j++) 20 | if(P[x][j - 1] != -1) P[x][j] = P[P[x][j - 1]][j- 1]; 21 | } 22 | 23 | inline int lca(int x, int y) { 24 | if(level[x] < level[y]) swap(x, y); 25 | int lg = 1; 26 | while((1 << lg) <= level[x]) lg++; lg--; 27 | for(int i = lg; i >= 0; i--) { 28 | if(level[x] - (1 << i) >= level[y]) x = P[x][i]; 29 | } 30 | if(x == y) return x; 31 | for(int i = lg; i >= 0; i--) { 32 | if(P[x][i] != -1 && P[x][i] != P[y][i]) x = P[x][i], y = P[y][i]; 33 | } 34 | return parent[x]; 35 | } 36 | -------------------------------------------------------------------------------- /rangeQuery.cpp: -------------------------------------------------------------------------------- 1 | // Range Query 2 | // O(nlogn) preprocessing, O(1) range query 3 | // change op(x, y) to any associative function 4 | // call init function before any query 5 | 6 | const int N = 100100; 7 | ll a[N]; 8 | ll dp[N][20]; // dp[i][j] stores function value of range of length 2^j starting from i 9 | int logVal[N]; // value of floor of log2 10 | 11 | ll gcd(ll x, ll y) { 12 | if(y == 0) return x; 13 | return gcd(y, x % y); 14 | } 15 | 16 | #define op(x, y) (gcd(x, y)) 17 | 18 | inline void init(int sz) { 19 | // initialize log table 20 | // in case of multiple test cases, use this just at the begining 21 | logVal[0] = -1; 22 | for(int i = 1; i < N; ++i) { 23 | logVal[i] = logVal[i - 1]; 24 | if((i & (i - 1)) == 0) ++logVal[i]; 25 | } 26 | 27 | for(int i = 0; i < sz; ++i) { 28 | dp[i][0] = a[i]; 29 | } 30 | 31 | for(int j = 1; (1 << j) <= sz; j++) { 32 | for(int i = 0; i + (1 << j) <= sz; i++) 33 | dp[i][j] = op(dp[i][j - 1] , dp[i + (1 << (j - 1))][j - 1]); 34 | } 35 | } 36 | 37 | inline ll rangeQuery(int l, int r) { 38 | int k = logVal[r - l + 1]; 39 | return op(dp[l][k], dp[r - (1 << k) + 1][k]); 40 | } -------------------------------------------------------------------------------- /LIS(nlogn).cpp: -------------------------------------------------------------------------------- 1 | /* Longest increasing subsequence O(n log n) */ 2 | /* Taken from Topcoder SRM 623 Div 1 - 450 ptr solution */ 3 | 4 | int LIS(int n, const vector & x) 5 | { 6 | int M[n+1]; 7 | int L = 0; 8 | for (int i = 0; i < n; i++) { 9 | // Binary search for the largest positive j ≤ L 10 | // such that X[M[j]] < X[i] 11 | int lo = 1; 12 | int hi = L; 13 | while (lo <= hi) { 14 | int mid = (lo + hi )/2; 15 | if (x[M[mid]] <= x[i]) { 16 | lo = mid+1; 17 | } else { 18 | hi = mid-1; 19 | } 20 | } 21 | 22 | // After searching, lo is 1 greater than the 23 | // length of the longest prefix of X[i] 24 | int newL = lo; 25 | 26 | if (newL > L) { 27 | // If we found a subsequence longer than any we've 28 | // found yet, update M and L 29 | M[newL] = i; 30 | L = newL; 31 | } else if (x[i] <= x[M[newL]]) { 32 | // If we found a smaller last value for the 33 | // subsequence of length newL, only update M 34 | M[newL] = i; 35 | } 36 | } 37 | return L; 38 | } -------------------------------------------------------------------------------- /FordFulkerson.cpp: -------------------------------------------------------------------------------- 1 | int par[N], graph[N][N]; 2 | bool vis[N]; 3 | stack stak; 4 | vector adj[N]; 5 | int source, sink; 6 | vector< pair< pair , int> > edges; 7 | 8 | inline bool FindAugPath(){ 9 | int u, v, i; 10 | memset(vis, false, sizeof(vis)); 11 | 12 | stak.push(1); 13 | vis[1] = true; 14 | 15 | while(!stak.empty()){ 16 | u = stak.top(); 17 | stak.pop(); 18 | 19 | if(vis[sink] == true){ 20 | continue; 21 | } 22 | 23 | for(i = adj[u].size() - 1; i >= 0; i--){ 24 | v = adj[u][i]; 25 | if(vis[v] == false){ 26 | if(graph[u][v] > 0){ 27 | par[v] = u; 28 | vis[v] = true; 29 | stak.push(v); 30 | } 31 | } 32 | } 33 | } 34 | 35 | if(vis[sink] == false){ 36 | return false; 37 | } 38 | 39 | u = sink; 40 | while(u != source){ 41 | graph[par[u]][u]--; 42 | graph[u][par[u]]++; 43 | u = par[u]; 44 | } 45 | 46 | return true; 47 | } 48 | 49 | inline int MaxFlow(){ 50 | int mf = 0; 51 | while(FindAugPath()){ 52 | mf++; 53 | } 54 | return mf; 55 | } 56 | -------------------------------------------------------------------------------- /Trie.cpp: -------------------------------------------------------------------------------- 1 | // Trie 2 | // Insert, Query - O(logn) 3 | // query and insert function needs to be changed according to need 4 | 5 | 6 | 7 | #define CHILD_SIZE 26 8 | 9 | int cnt[2][26]; 10 | 11 | struct node { 12 | node * child[CHILD_SIZE]; 13 | int cnt; 14 | 15 | node() { 16 | cnt = 0; 17 | for(int i = 0; i < CHILD_SIZE; ++i) 18 | child[i] = NULL; 19 | } 20 | 21 | void clear() { 22 | cnt = 0; 23 | for(int i = 0; i < CHILD_SIZE; ++i) { 24 | child[i] = NULL; 25 | } 26 | } 27 | }; 28 | 29 | struct Trie { 30 | private: 31 | void insert(node * cur, string s) { 32 | cur->cnt++; 33 | for(int i = 0; i < sz(s); ++i) { 34 | int curPos = s[i] - 'a'; 35 | if(cur->child[curPos] == NULL) { 36 | cur->child[curPos] = new node(); 37 | ++cntNodes; 38 | } 39 | cur = cur->child[curPos]; 40 | cur->cnt++; 41 | } 42 | } 43 | 44 | public: 45 | 46 | int cntNodes; 47 | node * root; 48 | 49 | Trie() { 50 | cntNodes = 0; 51 | root = new node(); 52 | } 53 | 54 | ~Trie() { 55 | delete root; 56 | } 57 | 58 | void clear() { 59 | cntNodes = 0; 60 | root = new node(); 61 | } 62 | }; -------------------------------------------------------------------------------- /template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | typedef long long lli; 7 | typedef pair pii; 8 | typedef vector vi; 9 | 10 | #define rep(i, n) for(int i = 0; i < (n); ++i) 11 | #define forn(i, a, b) for(int i = (a); i < (b); ++i) 12 | #define ford(i, a, b) for(int i = (a); i >= (b); --i) 13 | #define fore(i, a, b) forn(i, a, b + 1) 14 | 15 | #define pb push_back 16 | #define mp make_pair 17 | #define ff first 18 | #define ss second 19 | #define all(c) c.begin(), c.end() 20 | #define mset(a, v) memset(a, v, sizeof(a)) 21 | #define sz(a) ((int)a.size()) 22 | 23 | #define gi(x) scanf("%d", &x) 24 | #define pis(x) printf("%d ", x) 25 | #define pin(x) printf("%d\n", x) 26 | #define pnl printf("\n") 27 | #define dbn cerr << "\n" 28 | #define dbg(x) cerr << #x << " : " << (x) << " " 29 | #define dbs(x) cerr << (x) << " " 30 | 31 | #define foreach(c, it) for(__typeof(c.begin()) it = c.begin(); it != c.end(); ++it) 32 | 33 | #define dbg(...) dbs(#__VA_ARGS__, __VA_ARGS__) 34 | template void dbs(string str, T t) { 35 | cerr << str << " : " << t << "\n"; 36 | } 37 | template void dbs(string str, T t, S... s) { 38 | int idx = str.find(','); 39 | cerr << str.substr(0, idx) << " : " << t << ","; 40 | dbs(str.substr(idx + 1), s...); 41 | } 42 | 43 | int main() { 44 | ios::sync_with_stdio(false); 45 | cin.tie(NULL); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /EdmondsKarpMaxFlow.cpp: -------------------------------------------------------------------------------- 1 | /* Edmonds Karp algorithm (implementation of Ford Fulkerson method) for Max Flow 2 | Complexity O(EV^2) (practically much less than that) 3 | */ 4 | 5 | #define N 60 // Maximum number of nodes 6 | const int INF = 0x3f3f3f3f; 7 | 8 | struct MaxFlow 9 | { 10 | int adm[N][N]; // Stores capacities of DIRECTED edges 11 | int radm[N][N];// Residual Graph 12 | int par[N]; 13 | int visited[N]; 14 | 15 | MaxFlow() 16 | { 17 | memset(adm,0,sizeof(adm)); 18 | memset(radm,0,sizeof(radm)); 19 | } 20 | 21 | void addEdge(int a, int b, int cap) // Adds DIRECTED edge (a->b) with capactity cap 22 | { 23 | adm[a][b]+=cap; 24 | radm[a][b]+=cap; 25 | } 26 | 27 | int bfsFlow(int a, int b) 28 | { 29 | int temp; 30 | queue que; 31 | memset(visited,0,sizeof(visited)); 32 | par[a]=-1; visited[a]=1; 33 | que.push(a); 34 | while(que.size()) 35 | { 36 | temp=que.front(); 37 | que.pop(); 38 | for(int i=0;i0) 39 | { 40 | que.push(i); 41 | par[i]=temp; 42 | visited[i]=1; 43 | } 44 | } 45 | if(visited[b]==0) return 0; 46 | int path_flow=INF; 47 | int v=b; 48 | while(par[v]!=-1) 49 | { 50 | path_flow=min(path_flow,radm[par[v]][v]); 51 | v=par[v]; 52 | } 53 | v=b; 54 | while(par[v]!=-1) 55 | { 56 | radm[par[v]][v]-=path_flow; 57 | radm[v][par[v]]+=path_flow; 58 | v=par[v]; 59 | } 60 | return path_flow; 61 | } 62 | 63 | int maxFlow(int a, int b) // Returns max flow from a to b 64 | { 65 | int max_flow=0,path_flow=0; 66 | while((path_flow=bfsFlow(a,b))>0) max_flow+=path_flow; 67 | return max_flow; 68 | } 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /ConvexHullOptimization.cpp: -------------------------------------------------------------------------------- 1 | int pointer; //Keeps track of the best line from previous query 2 | vector M; //Holds the slopes of the lines in the envelope 3 | vector B; //Holds the y-intercepts of the lines in the envelope 4 | //Returns true if either line l1 or line l3 is always better than line l2 5 | bool bad(int l1,int l2,int l3) 6 | { 7 | /* 8 | intersection(l1,l2) has x-coordinate (b1-b2)/(m2-m1) 9 | intersection(l1,l3) has x-coordinate (b1-b3)/(m3-m1) 10 | set the former greater than the latter, and cross-multiply to 11 | eliminate division 12 | */ 13 | return (B[l3]-B[l1])*(M[l1]-M[l2])<(B[l2]-B[l1])*(M[l1]-M[l3]); 14 | } 15 | //Adds a new line (with lowest slope) to the structure 16 | void add(long long m,long long b) 17 | { 18 | //First, let's add it to the end 19 | M.push_back(m); 20 | B.push_back(b); 21 | //If the penultimate is now made irrelevant between the antepenultimate 22 | //and the ultimate, remove it. Repeat as many times as necessary 23 | while (M.size()>=3&&bad(M.size()-3,M.size()-2,M.size()-1)) 24 | { 25 | M.erase(M.end()-2); 26 | B.erase(B.end()-2); 27 | } 28 | } 29 | //Returns the minimum y-coordinate of any intersection between a given vertical 30 | //line and the lower envelope 31 | long long query(long long x) 32 | { 33 | //If we removed what was the best line for the previous query, then the 34 | //newly inserted line is now the best for that query 35 | if (pointer>=M.size()) 36 | pointer=M.size()-1; 37 | //Any better line must be to the right, since query values are 38 | //non-decreasing 39 | while (pointersize + r->size; 9 | } 10 | }; 11 | 12 | typedef node * pNode; 13 | 14 | void split(pNode x, int key, pNode & l, pNode & r) { 15 | if(!x) 16 | l = r = NULL; 17 | else if(key < x->key) { 18 | split(x->l, key, l, x->l); 19 | r = x; 20 | } else { 21 | split(x->r, key, x->r, r); 22 | l = x; 23 | } 24 | 25 | if(x) { 26 | if(x->l) x->l->update(); 27 | if(x->r) x->r->update(); 28 | x->update(); 29 | } 30 | } 31 | 32 | void insert(pNode & x, pNode y) { 33 | if(!x) 34 | x = y; 35 | else if(y->prior > x->prior) { 36 | split(x, y->key, y->l, y->r); 37 | x = y; 38 | } else { 39 | insert(y->key < x->key ? x->l : x->r, y); 40 | } 41 | 42 | if(x) { 43 | if(x->l) x->l->update(); 44 | if(x->r) x->r->update(); 45 | x->update(); 46 | } 47 | } 48 | 49 | void merge(pNode & x, pNode l, pNode r) { 50 | if(!l or !r) 51 | x = l ? l : r; 52 | else if(l->prior > r->prior) { 53 | merge(l->r, l->r, r); 54 | x = l; 55 | } else { 56 | merge(r->l, l, r->l); 57 | x = r; 58 | } 59 | 60 | if(x) { 61 | if(x->l) x->l->update(); 62 | if(x->r) x->r->update(); 63 | x->update(); 64 | } 65 | } 66 | 67 | void erase(pNode & x, int key) { 68 | if(!x) return; 69 | if(x->key == key) 70 | merge(x, x->l, x->r); 71 | else 72 | erase(key < x->key ? x->l : x->r, key); 73 | 74 | if(x) { 75 | if(x->l) x->l->update(); 76 | if(x->r) x->r->update(); 77 | x->update(); 78 | } 79 | } 80 | 81 | pNode join(pNode l, pNode r) { 82 | if(!l or !r) return l ? l : r; 83 | if(l->prior < r->prior) swap(l, r); 84 | pNode lt, rt; 85 | split(r, l->key, lt, rt); 86 | l->l = join(l->l, lt); 87 | l->r = join(l->r, rt); 88 | 89 | if(x) { 90 | if(x->l) x->l->update(); 91 | if(x->r) x->r->update(); 92 | x->update(); 93 | } 94 | 95 | return l; 96 | } 97 | -------------------------------------------------------------------------------- /DinicsFlow.cpp: -------------------------------------------------------------------------------- 1 | // Dinics Max Flow 2 | // To put lower bound on edge capacities form a new graph G' with source s' and t' 3 | // for each edge u->v in G with cap (low, high), replace it with 4 | // s'->v with low 5 | // v->t' with low 6 | // u->v with high - low 7 | 8 | const int inf = 0x3f3f3f3f; 9 | 10 | struct edge { 11 | int x, y, cap, flow; 12 | }; 13 | 14 | struct DinicFlow { 15 | vector e; 16 | vector cur, d; 17 | vector < vector > adj; 18 | int n, source, sink; 19 | 20 | DinicFlow() {} 21 | 22 | DinicFlow(int v) { 23 | n = v; 24 | cur = vector (n + 1); 25 | d = vector (n + 1); 26 | adj = vector < vector > (n + 1); 27 | } 28 | 29 | void addEdge(int from, int to, int cap) { 30 | edge e1 = {from, to, cap, 0}; 31 | edge e2 = {to, from, 0, 0}; 32 | adj[from].push_back(e.size()); e.push_back(e1); 33 | adj[to].push_back(e.size()); e.push_back(e2); 34 | } 35 | 36 | int bfs() { 37 | queue q; 38 | for(int i = 0; i <= n; ++i) d[i] = -1; 39 | q.push(source); d[source] = 0; 40 | while(!q.empty() and d[sink] < 0) { 41 | int x = q.front(); q.pop(); 42 | for(int i = 0; i < (int)adj[x].size(); ++i) { 43 | int id = adj[x][i], y = e[id].y; 44 | if(d[y] < 0 and e[id].flow < e[id].cap) { 45 | q.push(y); d[y] = d[x] + 1; 46 | } 47 | } 48 | } 49 | return d[sink] >= 0; 50 | } 51 | 52 | int dfs(int x, int flow) { 53 | if(!flow) return 0; 54 | if(x == sink) return flow; 55 | for(;cur[x] < (int)adj[x].size(); ++cur[x]) { 56 | int id = adj[x][cur[x]], y = e[id].y; 57 | if(d[y] != d[x] + 1) continue; 58 | int pushed = dfs(y, min(flow, e[id].cap - e[id].flow)); 59 | if(pushed) { 60 | e[id].flow += pushed; 61 | e[id ^ 1].flow -= pushed; 62 | return pushed; 63 | } 64 | } 65 | return 0; 66 | } 67 | 68 | int maxFlow(int src, int snk) { 69 | this->source = src; this->sink = snk; 70 | int flow = 0; 71 | while(bfs()) { 72 | for(int i = 0; i <= n; ++i) cur[i] = 0; 73 | while(int pushed = dfs(source, inf)) { 74 | flow += pushed; 75 | } 76 | } 77 | return flow; 78 | } 79 | }; -------------------------------------------------------------------------------- /SuffixAutomata.cpp: -------------------------------------------------------------------------------- 1 | /* Suffix automata code O(n) time complexity */ 2 | /* This code is taken from http://e-maxx.ru/algo/suffix_automata */ 3 | /* Array Version and Map Version. 4 | To convert to Map version comment the codes marked by 'Array version' and uncomment the codes marked by 'Map version' 5 | */ 6 | 7 | #define ALP 26 // Number of alphabets 8 | #define MAXLEN 100100 9 | 10 | struct state { 11 | int len, link; 12 | int next[ALP]; // Array Version //Stores next states for different transition symbols 13 | // map next; // Map version 14 | }; 15 | 16 | state st[MAXLEN*2]; 17 | int term[2*MAXLEN]; // Marks the terminal/final states. 18 | int sz, last; // sz = size of the automata 19 | 20 | void sa_init() // Initialize Suffix Automata 21 | { 22 | sz = last = 0; 23 | st[0].len = 0; 24 | st[0].link = -1; 25 | ++sz; 26 | 27 | // Array version 28 | for (int i=0; i 0, 'B'-> 1 and so on. 44 | */ 45 | void sa_extend (int c) 46 | { 47 | int cur = sz++; 48 | st[cur].len = st[last].len + 1; 49 | int p; 50 | 51 | //Array version 52 | for (p=last; p!=-1 && st[p].next[c]==-1; p=st[p].link) 53 | st[p].next[c] = cur; 54 | 55 | /* 56 | // Map version 57 | for (p=last; p!=-1 && !st[p].next.count(c); p=st[p].link) 58 | st[p].next[c] = cur; 59 | */ 60 | 61 | if (p == -1) 62 | st[cur].link = 0; 63 | else { 64 | int q = st[p].next[c]; 65 | if (st[p].len + 1 == st[q].len) 66 | st[cur].link = q; 67 | else { 68 | int clone = sz++; 69 | st[clone].len = st[p].len + 1; 70 | 71 | //Array version 72 | for(int i=0;i 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | typedef pair pii; 7 | typedef vector vi; 8 | 9 | #define rep(i, n) for(int i = 0; i < (n); ++i) 10 | #define forn(i, a, b) for(int i = (a); i < (b); ++i) 11 | #define ford(i, a, b) for(int i = (a); i >= (b); --i) 12 | #define fore(i, a, b) forn(i, a, b + 1) 13 | 14 | #define pb push_back 15 | #define mp make_pair 16 | #define ff first 17 | #define ss second 18 | #define all(c) c.begin(), c.end() 19 | #define mset(a, v) memset(a, v, sizeof(a)) 20 | #define sz(a) ((int)a.size()) 21 | 22 | #define gi(x) scanf("%d", &x) 23 | #define pis(x) printf("%d ", x) 24 | #define pin(x) printf("%d\n", x) 25 | #define pnl printf("\n") 26 | #define dbn cerr << "\n" 27 | #define dbg(x) cerr << #x << " : " << (x) << " " 28 | #define dbs(x) cerr << (x) << " " 29 | 30 | #define foreach(c, it) for(__typeof(c.begin()) it = c.begin(); it != c.end(); ++it) 31 | 32 | // change long double in typedef to double if TLE 33 | typedef complex complex_t; 34 | const long double PI = acos((long double)-1.0); 35 | 36 | void fft(vector & a, int s = 1) { 37 | int n = (int)a. size(); 38 | 39 | for (int i = 1, j = 0; i < n; ++i) { 40 | int bit = n >> 1 ; 41 | for (; j >= bit; bit >>= 1) 42 | j -= bit; 43 | j += bit; 44 | if (i < j) 45 | swap (a[i], a[j]); 46 | } 47 | 48 | for (int len = 2; len <= n; len <<= 1) { 49 | long double ang = 2 * s * PI / len; 50 | complex_t wlen(cos(ang), sin(ang)); 51 | for (int i = 0 ; i < n ; i += len) { 52 | complex_t w(1); 53 | for (int j = 0 ; j < len / 2 ; ++ j) { 54 | complex_t u = a[i + j] , v = a[i + j + len / 2] * w ; 55 | a[i + j] = u + v ; 56 | a[i + j + len / 2] = u - v ; 57 | w *= wlen ; 58 | } 59 | } 60 | } 61 | if (s == -1) 62 | for (int i = 0; i < n; ++i) 63 | a[i] /= n; 64 | } 65 | 66 | typedef long long ll; 67 | // change ll to complex_t if needed 68 | vector multiply (const vector& a, const vector& b) { 69 | vector fa(a.begin(), a.end()), fb(b.begin(), b.end()); 70 | int n = 1; 71 | while (n < max(a.size(), b.size())) 72 | n <<= 1; 73 | n <<= 1; 74 | fa.resize(n), fb.resize(n); 75 | 76 | fft(fa), fft(fb); 77 | 78 | for (int i = 0; i < n; ++i) 79 | fa[i] *= fb[i]; 80 | 81 | fft (fa, -1); 82 | 83 | vector res(n); 84 | for (size_t i = 0; i < n; ++i) 85 | res[i] = (ll) (fa[i].real() + 0.5); 86 | return res; 87 | } 88 | 89 | int main() { 90 | return 0; 91 | } -------------------------------------------------------------------------------- /geometry.hpp: -------------------------------------------------------------------------------- 1 | // type of coordinates 2 | typedef double pType; 3 | 4 | struct Point { 5 | pType x,y; 6 | Point() {} 7 | Point(pType x,pType y):x(x),y(y) {} 8 | 9 | // use brackets with all operators e.g use (a ^ b) instead of just a ^ b 10 | // vector addition 11 | Point operator +(const Point &rhs) const { return Point(this->x + rhs.x, this->y + rhs.y); } 12 | // vector subtraction 13 | Point operator -(const Point &rhs) const { return Point(this->x - rhs.x, this->y - rhs.y); } 14 | 15 | bool operator ==(const Point &rhs) const { return (this->x == rhs.x && this->y == rhs.y);} 16 | bool operator <(const Point &rhs) const { if(this->x != rhs.x) return this->x < rhs.x; return this->y < rhs.y;} 17 | // cross product 18 | pType operator ^(const Point &rhs) const { return this->x * rhs.y - this->y * rhs.x; } 19 | // dot product 20 | pType operator *(const Point &rhs) const { return this->x * rhs.x + this->y * rhs.y; } 21 | 22 | void print() { 23 | cout << "[" << x << " , " << y << "]"; 24 | } 25 | }; 26 | 27 | // scalar multiplication 28 | Point operator *(pType c, const Point &p) { return Point(c * p.x, c * p.y); } 29 | // square of length 30 | pType len2(const Point & p) { return p * p; } 31 | // square of distance between two vectors 32 | pType dis2(const Point & p, const Point & q) { return len2(p - q); } 33 | 34 | // convex hull (monotone chain) O(nlogn) 35 | // pass a vector of unique points 36 | vector convexHull(vector pts) { 37 | vector hull; 38 | sort(pts.begin(), pts.end()); 39 | int n = (int)pts.size(); 40 | 41 | hull.push_back(pts[0]); 42 | int nh = 1, start = 0; 43 | for(int i = 0; i < n; ++i) { 44 | Point p = pts[i]; 45 | while(nh - start >= 2 and ((p - hull[nh - 1]) ^ (hull[nh - 1] - hull[nh - 2])) >= 0) { 46 | hull.pop_back(); --nh; 47 | } 48 | hull.push_back(p); ++nh; 49 | } 50 | 51 | start = nh - 1; 52 | for(int i = n - 2; i >= 0; --i) { 53 | Point p = pts[i]; 54 | while(nh - start >= 2 and ((p - hull[nh - 1]) ^ (hull[nh - 1] - hull[nh - 2])) >= 0) { 55 | hull.pop_back(); --nh; 56 | } 57 | hull.push_back(p); ++nh; 58 | } 59 | hull.pop_back(); 60 | return hull; 61 | } 62 | 63 | // area of a convex hull of a vector of points 64 | double area(vector & pts) { 65 | sort(all(pts)); 66 | pts.erase(unique(all(pts)), pts.end()); 67 | if(sz(pts) <= 2) return 0.0; 68 | double ar = 0.0; 69 | vector hull = convexHull(pts); 70 | rep(i, sz(hull)) { 71 | ar += hull[i] ^ hull[(i + 1) % sz(hull)]; 72 | } 73 | return 0.5 * ar; 74 | } -------------------------------------------------------------------------------- /MinCostMaxFlow.cpp: -------------------------------------------------------------------------------- 1 | /* Shortest Path Faster Algorithm Paths Based for Min-Cost-Max Flow 2 | Complexity O(EV^3) (practically much less than that, way better than using Dijsktra) 3 | */ 4 | 5 | /* Min-Cost Max Flow implementation */ 6 | // MaxFlow and MinCost are lli 7 | // allows multiple edges between nodes 8 | // To check actual flow through edge[i] -> edge[i ^ 1].flow (would have positive value) 9 | 10 | typedef int fType; 11 | typedef int cType; 12 | 13 | const fType INF = 0x3f3f3f3f; 14 | 15 | struct edge { 16 | int u, v; 17 | fType flow; 18 | cType cost; 19 | edge() {} 20 | edge(int u, int v, fType f, cType c) : u(u), v(v), flow(f), cost(c) {} 21 | }; 22 | 23 | struct MinCostMaxFlow { 24 | int N; 25 | vector < vector > G; 26 | vector E; 27 | int numEdges; 28 | vector found, dad; 29 | vector dist; 30 | 31 | MinCostMaxFlow(int N): 32 | N(N), G(N), found(N), dist(N), dad(N), numEdges(0) {} 33 | 34 | void addEdge(int from, int to, fType capacity, cType cost) { 35 | G[from].push_back(numEdges++); 36 | E.push_back(edge(from, to, capacity, cost)); 37 | G[to].push_back(numEdges++); 38 | E.push_back(edge(to, from, 0, cType(-1) * cost)); 39 | } 40 | 41 | bool spfa(int s, int t) { 42 | fill(dad.begin(), dad.end(), -1); 43 | fill(dist.begin(), dist.end(), INF); 44 | fill(found.begin(), found.end(), 0); 45 | queue Q; 46 | dist[s] = 0; 47 | Q.push(s); 48 | found[s] = true; 49 | 50 | while(!Q.empty()) { 51 | int u = Q.front(); Q.pop(); 52 | if(u == t) continue; 53 | for (int i = 0; i < G[u].size(); ++i) { 54 | edge &pres = E[G[u][i]]; 55 | int v = pres.v; 56 | if(pres.flow <= 0) continue; 57 | if(dist[u] + pres.cost < dist[v]) { 58 | dad[v] = G[u][i]; 59 | dist[v] = dist[u] + pres.cost; 60 | if(!found[v]) Q.push(v), found[v] = true; 61 | } 62 | } 63 | found[u] = false; 64 | } 65 | return (dad[t] != -1); 66 | } 67 | 68 | fType dfs(int s,int t) { 69 | fType flow = INF; 70 | for(int i = dad[t]; i != -1; i = dad[E[i].u]) { 71 | if(E[i].flow < flow) flow = E[i].flow; 72 | } 73 | for(int i = dad[t]; i != -1; i = dad[E[i].u]) { 74 | E[i].flow -= flow; 75 | E[i ^ 1].flow += flow; 76 | } 77 | return flow; 78 | } 79 | 80 | pair getMaxFlow(int s, int t) { 81 | fType totflow = 0; 82 | cType totcost = 0; 83 | while(spfa(s,t)) { 84 | fType amt = dfs(s,t); 85 | totflow += amt; 86 | totcost += dist[t] * (cType)amt; 87 | } 88 | return make_pair(totflow, totcost); 89 | } 90 | }; 91 | -------------------------------------------------------------------------------- /SuffixArray.cpp: -------------------------------------------------------------------------------- 1 | // N is the maximum length of string 2 | // LG is the ceil of the log of max length + 1 3 | // rank[i] = rank of suffix starting from i in the sorted sequence 4 | // sa[i] = position of the suffix in the string which is at i'th rank 5 | // construciton - O(nlog^2n) 6 | // lcp for two indices - O(logn) 7 | 8 | #define N 100100 9 | #define LG 20 10 | int rank[N], sa[N], P[LG][N]; 11 | 12 | struct SuffixArray { 13 | int lg, len, cum[N]; 14 | struct node { 15 | int a, b, c; 16 | 17 | /* bool operator < (const node & r) const { 18 | if(a != r.a) 19 | return a < r.a; 20 | return b < r.b; 21 | } 22 | */ 23 | 24 | } L[N], tmp[N]; 25 | 26 | //counting sort 27 | inline int cSort(int idx) { 28 | int n = max(300, len + 2), sum = 0; 29 | for(int i = 0; i < n; i++) cum[i] = 0; 30 | for(int i = 0; i < len; i++) { 31 | if(idx) cum[L[i].a + 1]++; 32 | else cum[L[i].b + 1]++; 33 | } 34 | for(int i = 0; i < n; i++) sum += cum[i], cum[i] = sum - cum[i]; 35 | for(int i = 0; i < len; i++) { 36 | if(idx) tmp[cum[L[i].a + 1]++] = L[i]; 37 | else tmp[cum[L[i].b + 1]++] = L[i]; 38 | } 39 | for(int i = 0; i < len; i++) L[i] = tmp[i]; 40 | } 41 | 42 | // construct suffix array "sa" for given string 43 | void construct(string s) { 44 | len = (int)s.length(); lg = 1; 45 | for(int i = 0; i < len; i++) P[0][i] = int(s[i]); 46 | for(int shift = 1; shift < len; shift <<= 1, lg++) { 47 | for(int i = 0; i < len; i++) { 48 | L[i].a = P[lg - 1][i]; 49 | L[i].b = i + shift < len ? P[lg - 1][i + shift] : -1; 50 | L[i].c = i; 51 | } 52 | cSort(0); 53 | cSort(1); 54 | /* sort(L, L + len) */ 55 | for(int i = 0; i < len; i++) 56 | P[lg][L[i].c] = (i > 0 && L[i].a == L[i - 1].a && L[i].b == L[i - 1].b) ? P[lg][L[i - 1].c] : i; 57 | } 58 | lg--; 59 | for(int i = 0; i < len; i++) sa[i] = 0; 60 | for(int i = 0; i < len; i++) sa[P[lg][i]] = i; 61 | for(int i = 0; i < len; i++) rank[sa[i]] = i; 62 | } 63 | 64 | // construct longest common prefix for suffixes starting from i and j 65 | int lcp(int i, int j) { 66 | if(i == j) return len - i; 67 | int l = 0; 68 | for(int k = lg; k >= 0 && i < len && j < len; k--) { 69 | if(P[k][i] == P[k][j]) { 70 | i += 1 << k; 71 | j += 1 << k; 72 | l += 1 << k; 73 | } 74 | } 75 | return l; 76 | } 77 | 78 | // gives number of unique substrings 79 | long long numSubStrings() { 80 | long long cnt = ((long long) len * (len + 1)) / 2; 81 | for(int i = 1; i < len; i++) cnt -= lcp(sa[i], sa[i - 1]); 82 | return cnt; 83 | } 84 | }; -------------------------------------------------------------------------------- /Palindrome Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | /*Main code begins now */ 5 | const int alpha = 26; 6 | const int MAXN = 100040; 7 | 8 | 9 | struct node { 10 | int next[alpha]; // link to palindrome by adding alpha , 0 = NULL (not a palindrome) 11 | int len; // length of palindrome 12 | int link; // link to largest suffix palindrome 13 | int half_link; // link to largest palindrome of length <= len/2 14 | int cnt; // frequency of palindrome 15 | node(){ 16 | memset(next,0,sizeof(next)); 17 | cnt = 0; 18 | } 19 | }; 20 | /* 21 | Palindrome Tree : Creates all Palindromic Substrings with their Frequencies in O(n) 22 | T[1] = palindrome of length -1(Root for trie of odd length) 23 | T[0] = palindrome of length 0(Root for trie of even length) 24 | cnt : Contains frequency of palindrome of that node 25 | */ 26 | struct PalindromeTree{ 27 | string s; // string to work on 28 | node T[MAXN]; 29 | int ind; // present index in Tree 30 | int last; // index of last suffix 31 | int n; // present index in string 32 | void initTree(string A) { 33 | s = A; 34 | int len = s.length(); 35 | for(int i = 0;i T[ind].len){ 58 | T[ind].half_link = T[T[ind].half_link].link; 59 | } 60 | T[last].next[let] = ind++; 61 | } 62 | last = T[last].next[let]; 63 | T[last].cnt++; 64 | } 65 | }; 66 | PalindromeTree PT; 67 | 68 | // Driver Program : http://www.spoj.com/problems/NUMOFPAL/ 69 | int main() { 70 | string line; 71 | cin>>line; 72 | 73 | PT.initTree(line); 74 | for (int i = 0; i < line.length(); i++) { 75 | PT.addLetter(i); 76 | } 77 | 78 | long long ans = 0; 79 | for(int i = PT.ind-1;i>1;i--){ 80 | int link = PT.T[i].link; 81 | PT.T[link].cnt += PT.T[i].cnt; // update cnt for subtree rooted at i 82 | 83 | ans += PT.T[i].cnt; 84 | } 85 | 86 | printf("%lld\n",ans); 87 | 88 | return 0; 89 | } -------------------------------------------------------------------------------- /segmentTree.cpp: -------------------------------------------------------------------------------- 1 | // Segment Tree with lazy propagation 2 | // Edit the functions as required 3 | 4 | 5 | #define N 30300 6 | #define l(x) (x << 1) + 1 7 | #define r(x) (x << 1) + 2 8 | #define mid(l, r) ((l + r) >> 1) 9 | 10 | int a[N]; 11 | struct node { 12 | ll sum; 13 | ll val; 14 | bool push; 15 | 16 | inline void combine(const node & left, const node & right) { 17 | sum = left.sum + right.sum; // For max() change here 18 | } 19 | 20 | } T[N << 2]; 21 | 22 | struct segmentTree { 23 | int n; 24 | 25 | segmentTree(int m) : n(m) { 26 | build(0, 0, n - 1); 27 | } 28 | 29 | void build(int x, int l, int r) { 30 | T[x].val = 0; T[x].push = false; 31 | if(l == r) { 32 | T[x].sum = a[l]; 33 | return; 34 | } 35 | int m = (l + r) >> 1; 36 | build(l(x), l, m); 37 | build(r(x), m + 1, r); 38 | T[x].combine(T[l(x)], T[r(x)]); 39 | } 40 | 41 | inline void resolve(int x, int l, int r) { // For max() change lines of this function 42 | if(T[x].push) { 43 | T[x].sum = T[x].val * (r - l + 1); // To add the new value to the elements of the range 44 | // instead of replacing the current value and putting the new value, change = to += 45 | if(l != r) { 46 | T[l(x)].val = T[x].val; // Change to += to 'add' to the range and not 'replace' 47 | T[r(x)].val = T[x].val; // -do- 48 | T[l(x)].push = T[r(x)].push = true; 49 | } 50 | T[x].push = false; 51 | T[x].val = 0; 52 | } 53 | } 54 | 55 | void updateRange(int x, int l, int r, int ql, int qr, ll v) { 56 | resolve(x, l, r); 57 | if(l > qr || r < ql) return; 58 | if(l >= ql && r <= qr) { 59 | T[x].val = v; 60 | T[x].push = true; 61 | resolve(x, l, r); 62 | return; 63 | } 64 | int m = (l + r) >> 1; 65 | updateRange(l(x), l, m, ql, qr, v); 66 | updateRange(r(x), m + 1, r, ql, qr, v); 67 | T[x].combine(T[l(x)], T[r(x)]); 68 | } 69 | 70 | ll queryRange(int x, int l, int r, int ql, int qr) { 71 | resolve(x, l, r); 72 | if(l >= ql && r <= qr) return T[x].sum; 73 | ll ret = 0; 74 | int m = (l + r) >> 1; 75 | if(ql <= m) ret += queryRange(l(x), l, m, ql, qr); // For max() change these two lines 76 | if(qr > m) ret += queryRange(r(x), m + 1, r, ql, qr); 77 | return ret; 78 | } 79 | 80 | void update(int ql, int qr, ll v) { 81 | updateRange(0, 0, n - 1, ql, qr, v); 82 | } 83 | 84 | ll query(int ql, int qr) { 85 | return queryRange(0, 0, n - 1, ql, qr); 86 | } 87 | }; 88 | 89 | struct segmentTree { 90 | vi seg; 91 | int n; 92 | int type; 93 | int segN; 94 | 95 | segmentTree() {} 96 | 97 | segmentTree(int m, int type) : n(m), type(type) { 98 | int sz = n; 99 | int segN; 100 | for (segN = 2; segN < sz; segN <<= 1); 101 | seg.assign(segN * 2, -1); 102 | for (int i = 0; i < sz; ++i) { 103 | seg[segN + i] = nxt[i][type]; 104 | } 105 | for (int i = segN; --i; ) { 106 | seg[i] = max(seg[i << 1], seg[i << 1 | 1]); 107 | } 108 | } 109 | 110 | inline int query(int a, int b) { 111 | int segN = seg.size() >> 1; 112 | int ret = -1; 113 | for (a += segN, b += segN; a <= b; a >>= 1, b >>= 1) { 114 | if ( a & 1) ret = max(ret, seg[a++]); 115 | if (~b & 1) ret = max(ret, seg[b--]); 116 | } 117 | return ret; 118 | } 119 | 120 | 121 | }; 122 | 123 | node seg[2 * N]; // N is some power of two 124 | 125 | void add(int i, node x) 126 | { 127 | seg[i += N] = x; 128 | for(i /= 2; i; i /= 2) 129 | seg[i] = merge(seg[i * 2], seg[i * 2 + 1]); 130 | } 131 | 132 | node get(int l, int r) 133 | { 134 | node resL, resR; 135 | for(l += N, r += N; l < r; l /= 2, r /= 2) 136 | { 137 | if(l % 2) 138 | resL = merge(resL, seg[l++]); 139 | if(r % 2) 140 | resR = merge(seg[--r], resR); 141 | } 142 | return merge(resL, resR); 143 | } 144 | -------------------------------------------------------------------------------- /implicitTreap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | typedef pair pii; 7 | typedef vector vi; 8 | 9 | #define rep(i, n) for(int i = 0; i < (n); ++i) 10 | #define forn(i, a, b) for(int i = (a); i < (b); ++i) 11 | #define ford(i, a, b) for(int i = (a); i >= (b); --i) 12 | #define fore(i, a, b) forn(i, a, b + 1) 13 | 14 | #define pb push_back 15 | #define mp make_pair 16 | #define ff first 17 | #define ss second 18 | #define all(c) c.begin(), c.end() 19 | #define mset(a, v) memset(a, v, sizeof(a)) 20 | #define sz(a) ((int)a.size()) 21 | 22 | #define gi(x) scanf("%d", &x) 23 | #define pis(x) printf("%d ", x) 24 | #define pin(x) printf("%d\n", x) 25 | #define pnl printf("\n") 26 | #define dbn cerr << "\n" 27 | #define dbg(x) cerr << #x << " : " << (x) << " " 28 | #define dbs(x) cerr << (x) << " " 29 | 30 | #define foreach(c, it) for(__typeof(c.begin()) it = c.begin(); it != c.end(); ++it) 31 | 32 | const int N = 1000100; 33 | 34 | // binary search tree w.r.t key and heap w.r.t priority 35 | // implicitTreap has indices as keys 36 | // x->update() -> update values from its subtree 37 | // 38 | // printTreap(x) -> print treap rooted at x 39 | // 40 | // split(x, l, r, key, add) -> split treap rooted at x into l and r such that all keys in l < key, add is the offset for index 41 | // 42 | // merge(x, l, r) -> merge the subtrees rooted at l and r into x 43 | // 44 | // insert(x, pos, v) -> insert a node at position pos with value v 45 | // split the treap into [0, pos) and [pos, n) 46 | // merge the left treap with new node and then merge the tree back 47 | // 48 | // update -> first split [0, n) into [0, l) and [l, n) 49 | // -> then split [l, n) into [l, r] and [r + 1, n) 50 | // -> then do the required operation on treap containing [l, r] 51 | // -> lazy propagation can be implemented 52 | // 53 | // query -> repeat above procedure to obtain treap containing [l, r] 54 | // -> then return the corresponding value 55 | 56 | 57 | struct node { 58 | int cnt, val, prior; 59 | ll sum; 60 | node * l, * r; 61 | 62 | inline void update() { 63 | cnt = 1 + (l ? l->cnt : 0) + (r ? r->cnt : 0); 64 | sum = val + (l ? l->sum : 0) + (r ? r->sum : 0); 65 | } 66 | } mem[N]; 67 | 68 | typedef node * pNode; 69 | 70 | inline pNode newNode() { 71 | static int memPtr = 0; 72 | return mem + memPtr++; 73 | } 74 | 75 | void print(pNode x, int level = 0) { 76 | if(!x) return; 77 | if(x->l) { 78 | print(x->l, level + 1); 79 | } 80 | printf("%*s(%d, %lld, %d)\n", level * 2, "", x->val, x->sum, x->prior); 81 | if(x->r) { 82 | print(x->r, level + 1); 83 | } 84 | } 85 | 86 | #define printTreap(x) { dbs(#x); dbn; print(x); puts(""); } 87 | 88 | inline int size(pNode x) { 89 | return x ? x->cnt : 0; 90 | } 91 | 92 | inline ll sum(pNode x) { 93 | return x ? x->sum : 0; 94 | } 95 | 96 | void split(pNode x, pNode & l, pNode & r, int key, int add = 0) { 97 | if(!x) { 98 | l = r = NULL; 99 | return; 100 | } 101 | int curKey = add + size(x->l); 102 | if(key <= curKey) { 103 | split(x->l, l, x->l, key, add); 104 | r = x; 105 | } else { 106 | split(x->r, x->r, r, key, curKey + 1); 107 | l = x; 108 | } 109 | x->update(); 110 | } 111 | 112 | void merge(pNode & x, pNode l, pNode r) { 113 | if(!l or !r) 114 | x = l ? l : r; 115 | else if(l->prior > r->prior) { 116 | merge(l->r, l->r, r); 117 | x = l; 118 | } else { 119 | merge(r->l, l, r->l); 120 | x = r; 121 | } 122 | if(x) x->update(); 123 | } 124 | 125 | inline void insert(pNode & T, int pos, int v) { 126 | node * cur = newNode(); 127 | cur->val = cur->sum = v; 128 | cur->prior = rand(); 129 | cur->cnt = 1; 130 | cur->l = cur->r = NULL; 131 | pNode l, r; 132 | split(T, l, r, pos); 133 | merge(l, l, cur); 134 | merge(T, l, r); 135 | } 136 | 137 | inline void update(pNode & T, int pos, int v) { 138 | pNode l, m, r; 139 | split(T, l, m, pos); 140 | split(m, m, r, 1); 141 | 142 | if(m) { 143 | m->sum = m->val = v; 144 | } 145 | 146 | merge(T, l, m); 147 | merge(T, T, r); 148 | } 149 | 150 | inline ll getSum(pNode & T, int ql, int qr) { 151 | pNode l, m, r; 152 | 153 | split(T, l, m, ql); 154 | split(m, m, r, qr - ql + 1); 155 | 156 | ll ret = sum(m); 157 | 158 | merge(T, l, m); 159 | merge(T, T, r); 160 | 161 | return ret; 162 | } -------------------------------------------------------------------------------- /Formulae.tex: -------------------------------------------------------------------------------- 1 | \documentclass[landscape, a4paper, onecolumn]{article} 2 | \usepackage{times,url,color,graphicx,epsfig} 3 | \usepackage{amsmath, amsthm, amssymb} 4 | \usepackage[ruled,vlined,linesnumbered,algoruled]{algorithm2e} 5 | \renewcommand{\baselinestretch}{1.2} 6 | 7 | 8 | \setlength{\textheight}{7.00in} 9 | \setlength{\textwidth}{9.50in} 10 | %\setlength{\columnsep}{0.375in} 11 | \setlength{\topmargin}{-0.5in} 12 | \setlength{\headheight}{0.0in} 13 | \setlength{\headsep}{0in} 14 | \setlength{\parindent}{0pc} 15 | \setlength{\parskip}{0.25pc} 16 | \setlength{\oddsidemargin}{0.00in} % Centers text. 17 | % \setlength{\evensidemargin}{1.00in} 18 | 19 | \newtheorem {thm} {Theorem} 20 | \newtheorem {dfn} {Definition} 21 | \newtheorem {lemma} {Lemma} 22 | 23 | \newcommand {\zero} {\sf O} 24 | \newcommand{\bigO}[1]{\ensuremath{\mathop{}\mathopen{}\mathcal{O}\mathopen{}\left(#1\right)}} 25 | 26 | \begin{document} 27 | \title{Team Notebook - Team BitBees - Indian Institute of Technology Kharagpur} 28 | \author{Anmol Gulati, Anurag Anand, Biswajit Paria} 29 | \date{} 30 | \maketitle 31 | 32 | \begin{verbatim} 33 | // Template 34 | #include 35 | using namespace std; 36 | typedef long long ll; 37 | typedef pair pii; 38 | typedef vector vi; 39 | 40 | #define rep(i, n) for(int i = 0; i < (n); ++i) 41 | #define forn(i, a, b) for(int i = (a); i < (b); ++i) 42 | 43 | #define pb push_back 44 | #define mp make_pair 45 | #define ff first 46 | #define ss second 47 | #define all(c) c.begin(), c.end() 48 | #define mset(a, v) memset(a, v, sizeof(a)) 49 | #define sz(a) ((int)a.size()) 50 | #define gi(x) scanf("%d", &x) 51 | #define dbn cerr << "\n" 52 | #define dbg(x) cerr << #x << " : " << (x) << " " 53 | #define dbs(x) cerr << (x) << " " 54 | 55 | #define foreach(c, it) for(__typeof(c.begin()) it = c.begin(); it != c.end(); ++it) 56 | 57 | int main() { 58 | return 0; // Don’t forget 59 | } 60 | 61 | \end{verbatim} 62 | 63 | \textbf{Sums} 64 | {\small 65 | \begin{eqnarray} 66 | \nonumber\sum_{k=0}^{n} k^4 &=& \frac{(6n^5+15n^4+10n^3-n)}{30}\\ 67 | \nonumber\sum_{k=0}^{n} k^5 &=& \frac{(2n^6+6n^5+5n^4-n^2)}{12}\\ 68 | \nonumber\sum_{k=0}^{n} kx^k &=& \frac{(x-(n+1)x^{n+1}+nx^{n+2}}{(x-1)^2} 69 | \end{eqnarray} 70 | } 71 | 72 | \textbf{Derangements} 73 | $D_n = (n-1)(D_{n-1}+D_{n-2}) = nD_{n-1}+(-1)^n$ 74 | 75 | \textbf{Stirling Numbers of 1st kind}. $s_{n,k}$ is $(-1)^{n-k}$ times the number of permutations of $n$ elements with exactly $k$ permutation cycles. $|s_{n,k}| = |s_{n-1,k-1}|+(n-1)|s_{n-1,k}$. $\sum_{k=0}^n s_{n,k}x^k = x^n$. 76 | 77 | \textbf{Stirling Numbers of 2nd kind}. $S_{n,k}$ is the number of ways to partition a set of $n$ elements with exactly $k$ non-empty subsets. $S_{n,k} = S_{n-1,k-1}+kS_{n-1,k}$. $S_{n,1} = S_{n,n} = 1$. $\sum_{k=0}^n S_{n,k}x^k = x^n$. 78 | 79 | \textbf{Chinese Remainder Theorem} 80 | System $x \equiv a_i \pmod{m_i}$ for $i = 1,\cdots,n$ with pairwise relatively prime $m_i$ has a unique solution modulo $M = m_1m_2\cdots m_n: x = \sum_{i=1}^{n} a_ib_i\frac{M}{m_i} \pmod{M}$ 81 | 82 | System $x \equiv a \pmod{m}, x \equiv b \pmod{m}$, has solution iff $a \equiv b \pmod{g}$, where $g = \gcd(m,n)$. The solution is unique modulo $L = \frac{mn}{g}$, and equals $x \equiv a + T(b-a)m/g \equiv b + S(a-b)n/g \pmod{L}$, where $S$ and $T$ are integer solutions of $mT + nS = \gcd(m,n)$. 83 | 84 | \textbf{Mobius Function} 85 | $\mu(1) = 1$. $\mu(n) = 0$, if $n$ is not square free. $\mu(n) = (-1)^s$, if $n$ is the product of $s$ distinct primes. Let $f, F$ be functions on positive integers. If $ \forall n \in \mathbb{N}, F(n) = \sum_{d|n} f(d)$, then $f(n) = \sum_{d|n} \mu(d)F(n/d)$ and vice versa. $\phi(n) = \sum_{d|n} \mu(d)(n/d)$. $\sum_{d|n} \mu(d) = 1$. If $f$ is multiplicative, then $\sum_{d|n} \mu(d)f(d) = \prod_{p|n}(1-f(p), \sum_{d|n} \mu(d)^2 f(d) = \prod_{p|n} (1+f(p)$. 86 | 87 | \textbf{Postage stamp problem} 88 | Let $a, b$ be relatively prime integers. There are exactly $\frac{1}{2}(a-1)(b-1)$ numbers not of the form $ax + by$ where $x,y \ge 0$ and the largest is $(a-1)(b-1)-1$. 89 | 90 | \textbf{Fermat's two square theorem} 91 | Odd prime $p$ can be represented as sum of two squares iff $p \equiv 1 \pmod{4}$. Product of two sums of two squares is a sum of two squares. Thus $n$ is a sum of two square iff every prime of the form $ p = 4k+3$ occurs an even number of times in the factorization of $n$. 92 | 93 | \textbf{Pick's Theorem} 94 | $I = A - B/2 +1$ where $A$ is the area of a lattice polygon, $I$ is number of lattice 95 | points inside it, and $B$ is number of lattice points on the boundary. Number of lattice points minus 96 | one on a line segment from $(0,0)$ and $(x,y)$ is $\gcd(x,y)$. 97 | 98 | \textbf{Angular Bisector} of $\angle ABC$ is line $BD$, where $D = \frac{BA}{|BA|} + \frac{BC}{|BC|}$. Center of incircle of $\Delta ABC$ is $\frac{a}{a+b+c} A + \frac{b}{a+b+c} B + \frac{c}{a+b+c} C$. Radius of incircle = $\frac{2\Delta}{a+b+c}$. 99 | 100 | \end{document} 101 | -------------------------------------------------------------------------------- /BigIntClasses.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | typedef long long LL; 9 | // base and base_digits must be consistent 10 | const int base = 1000000000; 11 | const int base_digits = 9; 12 | 13 | struct bigint { 14 | vector a; 15 | int sign; 16 | 17 | bigint() : 18 | sign(1) { 19 | } 20 | 21 | bigint(long long v) { 22 | *this = v; 23 | } 24 | 25 | bigint(const string &s) { 26 | read(s); 27 | } 28 | 29 | void operator=(const bigint &v) { 30 | sign = v.sign; 31 | a = v.a; 32 | } 33 | 34 | void operator=(long long v) { 35 | sign = 1; 36 | if (v < 0) 37 | sign = -1, v = -v; 38 | for (; v > 0; v = v / base) 39 | a.push_back(v % base); 40 | } 41 | 42 | bigint operator+(const bigint &v) const { 43 | if (sign == v.sign) { 44 | bigint res = v; 45 | 46 | for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) { 47 | if (i == (int) res.a.size()) 48 | res.a.push_back(0); 49 | res.a[i] += carry + (i < (int) a.size() ? a[i] : 0); 50 | carry = res.a[i] >= base; 51 | if (carry) 52 | res.a[i] -= base; 53 | } 54 | return res; 55 | } 56 | return *this - (-v); 57 | } 58 | 59 | bigint operator-(const bigint &v) const { 60 | if (sign == v.sign) { 61 | if (abs() >= v.abs()) { 62 | bigint res = *this; 63 | for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) { 64 | res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0); 65 | carry = res.a[i] < 0; 66 | if (carry) 67 | res.a[i] += base; 68 | } 69 | res.trim(); 70 | return res; 71 | } 72 | return -(v - *this); 73 | } 74 | return *this + (-v); 75 | } 76 | 77 | void operator*=(int v) { 78 | if (v < 0) 79 | sign = -sign, v = -v; 80 | for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) { 81 | if (i == (int) a.size()) 82 | a.push_back(0); 83 | long long cur = a[i] * (long long) v + carry; 84 | carry = (int) (cur / base); 85 | a[i] = (int) (cur % base); 86 | //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base)); 87 | } 88 | trim(); 89 | } 90 | 91 | bigint operator*(int v) const { 92 | bigint res = *this; 93 | res *= v; 94 | return res; 95 | } 96 | 97 | friend pair divmod(const bigint &a1, const bigint &b1) { 98 | int norm = base / (b1.a.back() + 1); 99 | bigint a = a1.abs() * norm; 100 | bigint b = b1.abs() * norm; 101 | bigint q, r; 102 | q.a.resize(a.a.size()); 103 | 104 | for (int i = a.a.size() - 1; i >= 0; i--) { 105 | r *= base; 106 | r += a.a[i]; 107 | int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()]; 108 | int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1]; 109 | int d = ((long long) base * s1 + s2) / b.a.back(); 110 | r -= b * d; 111 | while (r < 0) 112 | r += b, --d; 113 | q.a[i] = d; 114 | } 115 | 116 | q.sign = a1.sign * b1.sign; 117 | r.sign = a1.sign; 118 | q.trim(); 119 | r.trim(); 120 | return make_pair(q, r / norm); 121 | } 122 | 123 | bigint operator/(const bigint &v) const { 124 | return divmod(*this, v).first; 125 | } 126 | 127 | bigint operator%(const bigint &v) const { 128 | return divmod(*this, v).second; 129 | } 130 | 131 | void operator/=(int v) { 132 | if (v < 0) 133 | sign = -sign, v = -v; 134 | for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) { 135 | long long cur = a[i] + rem * (long long) base; 136 | a[i] = (int) (cur / v); 137 | rem = (int) (cur % v); 138 | } 139 | trim(); 140 | } 141 | 142 | bigint operator/(int v) const { 143 | bigint res = *this; 144 | res /= v; 145 | return res; 146 | } 147 | 148 | int operator%(int v) const { 149 | if (v < 0) 150 | v = -v; 151 | int m = 0; 152 | for (int i = a.size() - 1; i >= 0; --i) 153 | m = (a[i] + m * (long long) base) % v; 154 | return m * sign; 155 | } 156 | 157 | void operator+=(const bigint &v) { 158 | *this = *this + v; 159 | } 160 | void operator-=(const bigint &v) { 161 | *this = *this - v; 162 | } 163 | void operator*=(const bigint &v) { 164 | *this = *this * v; 165 | } 166 | void operator/=(const bigint &v) { 167 | *this = *this / v; 168 | } 169 | 170 | bool operator<(const bigint &v) const { 171 | if (sign != v.sign) 172 | return sign < v.sign; 173 | if (a.size() != v.a.size()) 174 | return a.size() * sign < v.a.size() * v.sign; 175 | for (int i = a.size() - 1; i >= 0; i--) 176 | if (a[i] != v.a[i]) 177 | return a[i] * sign < v.a[i] * sign; 178 | return false; 179 | } 180 | 181 | bool operator>(const bigint &v) const { 182 | return v < *this; 183 | } 184 | bool operator<=(const bigint &v) const { 185 | return !(v < *this); 186 | } 187 | bool operator>=(const bigint &v) const { 188 | return !(*this < v); 189 | } 190 | bool operator==(const bigint &v) const { 191 | return !(*this < v) && !(v < *this); 192 | } 193 | bool operator!=(const bigint &v) const { 194 | return *this < v || v < *this; 195 | } 196 | 197 | void trim() { 198 | while (!a.empty() && !a.back()) 199 | a.pop_back(); 200 | if (a.empty()) 201 | sign = 1; 202 | } 203 | 204 | bool isZero() const { 205 | return a.empty() || (a.size() == 1 && !a[0]); 206 | } 207 | 208 | bigint operator-() const { 209 | bigint res = *this; 210 | res.sign = -sign; 211 | return res; 212 | } 213 | 214 | bigint abs() const { 215 | bigint res = *this; 216 | res.sign *= res.sign; 217 | return res; 218 | } 219 | 220 | long long longValue() const { 221 | long long res = 0; 222 | for (int i = a.size() - 1; i >= 0; i--) 223 | res = res * base + a[i]; 224 | return res * sign; 225 | } 226 | 227 | friend bigint gcd(const bigint &a, const bigint &b) { 228 | return b.isZero() ? a : gcd(b, a % b); 229 | } 230 | friend bigint lcm(const bigint &a, const bigint &b) { 231 | return a / gcd(a, b) * b; 232 | } 233 | 234 | void read(const string &s) { 235 | sign = 1; 236 | a.clear(); 237 | int pos = 0; 238 | while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) { 239 | if (s[pos] == '-') 240 | sign = -sign; 241 | ++pos; 242 | } 243 | for (int i = s.size() - 1; i >= pos; i -= base_digits) { 244 | int x = 0; 245 | for (int j = max(pos, i - base_digits + 1); j <= i; j++) 246 | x = x * 10 + s[j] - '0'; 247 | a.push_back(x); 248 | } 249 | trim(); 250 | } 251 | 252 | int length(){ 253 | int l=0,back=a.back(); 254 | while(back){l++;back/=10;} 255 | l+=((a.size()-1)*base_digits); 256 | return l; 257 | } 258 | 259 | friend istream& operator>>(istream &stream, bigint &v) { 260 | string s; 261 | stream >> s; 262 | v.read(s); 263 | return stream; 264 | } 265 | 266 | friend ostream& operator<<(ostream &stream, const bigint &v) { 267 | if (v.sign == -1) 268 | stream << '-'; 269 | stream << (v.a.empty() ? 0 : v.a.back()); 270 | for (int i = (int) v.a.size() - 2; i >= 0; --i) 271 | stream << setw(base_digits) << setfill('0') << v.a[i]; 272 | return stream; 273 | } 274 | 275 | static vector convert_base(const vector &a, int old_digits, int new_digits) { 276 | vector p(max(old_digits, new_digits) + 1); 277 | p[0] = 1; 278 | for (int i = 1; i < (int) p.size(); i++) 279 | p[i] = p[i - 1] * 10; 280 | vector res; 281 | long long cur = 0; 282 | int cur_digits = 0; 283 | for (int i = 0; i < (int) a.size(); i++) { 284 | cur += a[i] * p[cur_digits]; 285 | cur_digits += old_digits; 286 | while (cur_digits >= new_digits) { 287 | res.push_back(int(cur % p[new_digits])); 288 | cur /= p[new_digits]; 289 | cur_digits -= new_digits; 290 | } 291 | } 292 | res.push_back((int) cur); 293 | while (!res.empty() && !res.back()) 294 | res.pop_back(); 295 | return res; 296 | } 297 | 298 | typedef vector vll; 299 | 300 | static vll karatsubaMultiply(const vll &a, const vll &b) { 301 | int n = a.size(); 302 | vll res(n + n); 303 | if (n <= 32) { 304 | for (int i = 0; i < n; i++) 305 | for (int j = 0; j < n; j++) 306 | res[i + j] += a[i] * b[j]; 307 | return res; 308 | } 309 | 310 | int k = n >> 1; 311 | vll a1(a.begin(), a.begin() + k); 312 | vll a2(a.begin() + k, a.end()); 313 | vll b1(b.begin(), b.begin() + k); 314 | vll b2(b.begin() + k, b.end()); 315 | 316 | vll a1b1 = karatsubaMultiply(a1, b1); 317 | vll a2b2 = karatsubaMultiply(a2, b2); 318 | 319 | for (int i = 0; i < k; i++) 320 | a2[i] += a1[i]; 321 | for (int i = 0; i < k; i++) 322 | b2[i] += b1[i]; 323 | 324 | vll r = karatsubaMultiply(a2, b2); 325 | for (int i = 0; i < (int) a1b1.size(); i++) 326 | r[i] -= a1b1[i]; 327 | for (int i = 0; i < (int) a2b2.size(); i++) 328 | r[i] -= a2b2[i]; 329 | 330 | for (int i = 0; i < (int) r.size(); i++) 331 | res[i + k] += r[i]; 332 | for (int i = 0; i < (int) a1b1.size(); i++) 333 | res[i] += a1b1[i]; 334 | for (int i = 0; i < (int) a2b2.size(); i++) 335 | res[i + n] += a2b2[i]; 336 | return res; 337 | } 338 | 339 | bigint operator*(const bigint &v) const { 340 | vector a6 = convert_base(this->a, base_digits, 6); 341 | vector b6 = convert_base(v.a, base_digits, 6); 342 | vll a(a6.begin(), a6.end()); 343 | vll b(b6.begin(), b6.end()); 344 | while (a.size() < b.size()) 345 | a.push_back(0); 346 | while (b.size() < a.size()) 347 | b.push_back(0); 348 | while (a.size() & (a.size() - 1)) 349 | a.push_back(0), b.push_back(0); 350 | vll c = karatsubaMultiply(a, b); 351 | bigint res; 352 | res.sign = sign * v.sign; 353 | for (int i = 0, carry = 0; i < (int) c.size(); i++) { 354 | long long cur = c[i] + carry; 355 | res.a.push_back((int) (cur % 1000000)); 356 | carry = (int) (cur / 1000000); 357 | } 358 | res.a = convert_base(res.a, 6, base_digits); 359 | res.trim(); 360 | return res; 361 | } 362 | }; 363 | 364 | --------------------------------------------------------------------------------