├── Pair.java ├── README.md ├── base.cpp ├── base.java ├── data_structures ├── BIT.cpp ├── MinQueue.cpp ├── hld_edge.cpp ├── hld_vertex.cpp ├── implicit_segtree.cpp ├── merge_tree.cpp ├── persistent_seg_tree.cpp ├── seg2d.cpp ├── seg_tree.cpp └── sparse_table.cpp ├── files.json ├── graph ├── 2_sat_cnf.cpp ├── BellmanFord.cpp ├── Dijkstra.cpp ├── EdmondsKarp.cpp ├── EdmondsKarp2.cpp ├── MaxFlowMinCost.cpp ├── centroid_decomposition.cpp ├── dfs.cpp ├── dinic.cpp ├── floyd.cpp ├── kruskal.cpp ├── kuhn.cpp ├── kuhn2.cpp └── lca.cpp ├── int128.cpp ├── judge.py ├── math ├── EulerTotient.cpp ├── Fibbonacci_MatrixExpo.cpp ├── LinearSieve.cpp ├── Makefile_brute ├── baby_giant_step.cpp ├── combinatorics.cpp ├── crt.cpp ├── extended_euclidean.cpp ├── fft.cpp ├── gauss_elim.cpp ├── gcd.cpp ├── geometry │ ├── convex_hull.cpp │ ├── geometry.cpp │ ├── geometryT.cpp │ └── point.cpp ├── karatsuba.cpp ├── millerRabin_pollardRho.cpp ├── ntt.cpp ├── ntt_constants.txt ├── pre_ntt.cpp └── stirling1.cpp ├── sites.md ├── strings ├── FiniteStateMachinePrefixFunction.cpp ├── Kmp.cpp ├── Manacher.cpp ├── SuffixAutomaton.cpp ├── SuffixAutomaton_base.cpp ├── SuffixAutomaton_class.cpp ├── Z.cpp ├── hash.cpp └── trie.cpp ├── tester.py ├── tmux.conf ├── trick ├── ConvexHullTrick.cpp ├── ConvexHullTrick1.cpp ├── DivideConquer.cpp ├── MosAlgorithm.cpp ├── mo_tree.cpp └── sub_super_masks.cpp └── vimrc /Pair.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | 5 | public class a { 6 | static Scanner in; 7 | 8 | public static void main(String[] args) { 9 | TreeSet > s = new TreeSet >(); 10 | in = new Scanner(System.in); 11 | while (in.hasNext()) { 12 | int a = in.nextInt(); 13 | double b = in.nextDouble(); 14 | s.add(new Pair(a, b)); 15 | } 16 | Iterator > it = s.iterator(); 17 | while (it.hasNext()) { 18 | Pair p = it.next(); 19 | System.out.println(p.fi + " " + p.se); 20 | } 21 | System.out.println(); 22 | } 23 | 24 | } 25 | 26 | class Pair,B extends Comparable> implements Comparable> { 27 | public A fi; 28 | public B se; 29 | 30 | Pair () {} 31 | 32 | Pair (A a, B b) { 33 | fi = a; se = b; 34 | } 35 | 36 | @Override 37 | public int compareTo (Pair p2) { 38 | int r = this.fi.compareTo(p2.fi); 39 | if (r != 0) return r; 40 | return this.se.compareTo(p2.se); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RepGod 2 | 3 | Competitive Programming Repository 4 | -------------------------------------------------------------------------------- /base.cpp: -------------------------------------------------------------------------------- 1 | // g++ .cpp -Wall -Wno-unused-value -DDEBUG 2 | #include 3 | 4 | using namespace std; 5 | 6 | #define pb push_back 7 | #define eb emplace_back 8 | #define mk make_pair 9 | #define fi first 10 | #define se second 11 | 12 | typedef long long ll; 13 | typedef __int128 LL; 14 | typedef pair ii; 15 | const int INF = 0x3f3f3f3f; 16 | const double PI = acos(-1.0); 17 | 18 | template 19 | std::ostream& operator<< (std::ostream& out, const vector& v) { 20 | out << '['; 21 | bool f = false; 22 | for(auto& x:v){ 23 | if (f) out<<", "; 24 | f = true; 25 | out< vec_splitter(string s) { 31 | s += ','; 32 | vector res; 33 | while(!s.empty()) { 34 | res.push_back(s.substr(0, s.find(','))); 35 | s = s.substr(s.find(',') + 1); 36 | } 37 | return res; 38 | } 39 | void debug_out( 40 | vector __attribute__ ((unused)) args, 41 | __attribute__ ((unused)) int idx, 42 | __attribute__ ((unused)) int LINE_NUM) { cerr << endl; } 43 | template 44 | void debug_out(vector args, int idx, int LINE_NUM, Head H, Tail... T) { 45 | if(idx > 0) cerr << ", "; else cerr << "Line(" << LINE_NUM << ") "; 46 | stringstream ss; ss << H; 47 | cerr << args[idx] << " = " << ss.str(); 48 | debug_out(args, idx + 1, LINE_NUM, T...); 49 | } 50 | 51 | #ifdef DEBUG 52 | #define debug(...) debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__) 53 | #define debug_endl() cout << endl; 54 | #else 55 | #define debug(...) 42 56 | #define debug_endl(...) 42 57 | #endif 58 | 59 | int main (void) { 60 | ios_base::sync_with_stdio(false); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /base.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | import java.math.BigInteger; 3 | import java.util.ArrayList; //vector 4 | import java.util.Collections; 5 | import java.io.File; 6 | import java.io.PrintWriter; 7 | import java.util.Arrays; 8 | import java.util.LinkedList; //queue 9 | import java.io.PrintStream; 10 | import java.util.TreeSet; //set 11 | import java.util.Iterator; 12 | import java.util.TreeMap; 13 | import java.util.Map; 14 | 15 | public class base { 16 | static PrintWriter writer; 17 | static Scanner in; 18 | static PrintStream out = System.out; 19 | 20 | public static void main (String[] args) throws Exception{ 21 | // writer = new PrintWriter("System.out", "UTF-8"); 22 | // in = new Scanner (new File("file.in")); 23 | in = new Scanner (System.in); 24 | 25 | in.close(); 26 | // writer.close(); 27 | } 28 | } 29 | 30 | class set { 31 | TreeSet s; 32 | 33 | void imp () { 34 | Iterator it = s.iterator(); 35 | while (it.hasNext()) System.out.print(it.next() + " "); 36 | System.out.println(); 37 | } 38 | } 39 | 40 | class map { 41 | public TreeMap m = new TreeMap(); 42 | K key; 43 | V value; 44 | 45 | map () {} 46 | 47 | void example () { 48 | boolean f; 49 | m.put(key, value); 50 | f = m.containsKey(key); f = m.containsValue(value); 51 | value = m.get(key); 52 | value = m.remove(key); 53 | } 54 | 55 | public void imp () { 56 | for (Map.Entry e : m.entrySet()) { 57 | key = e.getKey(); value = e.getValue(); 58 | System.out.println(key + " => " + value); 59 | } 60 | 61 | for (Iterator> it = m.entrySet().iterator(); it.hasNext(); ) { 62 | Map.Entry e = it.next(); 63 | System.out.println(e.getKey() + " => " + e.getValue()); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /data_structures/BIT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | const int N = 1e5 + 5; 8 | ll v[N]; // valores iniciais 9 | 10 | class BIT { 11 | private: 12 | ll t1[N], t2[N]; 13 | 14 | /* upd t[at..N]*/ 15 | void update (ll t[], int at, ll val) { 16 | for ( ; at <= N; at += at&(-at)) 17 | t[at] += val; 18 | } 19 | 20 | /* point query*/ 21 | ll query (ll t[], int b) { 22 | ll sum = v[b]; 23 | for (; b > 0; b -= b&(-b)) 24 | sum += t[b]; 25 | return sum; 26 | } 27 | 28 | /* query [1..b]*/ 29 | ll query (int b) { 30 | return query (t1, b) * b - query (t2, b); 31 | } 32 | 33 | public: 34 | /* upd t[a..b]*/ 35 | void update (ll a, ll b, ll val) { 36 | update (t1, a, val); 37 | update (t1, b + 1, -val); 38 | update (t2, a, val * (a-1)); 39 | update (t2, b + 1, -val * b); 40 | } 41 | 42 | /* query [a..b]*/ 43 | ll query (int a, int b) { 44 | return query(b) - query(a-1); 45 | } 46 | 47 | BIT () { 48 | memset (t1, 0, sizeof t1); 49 | memset (t2, 0, sizeof t2); 50 | } 51 | }; 52 | 53 | int main (void) { 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /data_structures/MinQueue.cpp: -------------------------------------------------------------------------------- 1 | /* MinQueue that stores a maximum of k elements */ 2 | #include 3 | 4 | using namespace std; 5 | 6 | #define pb push_back 7 | #define eb emplace_back 8 | #define mk make_pair 9 | #define fi first 10 | #define se second 11 | 12 | typedef long long ll; 13 | typedef pair ii; 14 | const int INF = 0x3f3f3f3f; 15 | const double PI = acos(-1.0); 16 | 17 | struct minq { 18 | deque v; 19 | int t, k; 20 | 21 | minq(int k) : k(k) {} 22 | 23 | void clear() { 24 | v.clear(); 25 | t = 0; 26 | } 27 | 28 | void insert(int at) { 29 | while(v.size() and (v.rbegin())->fi >= at) 30 | v.pop_back(); 31 | 32 | v.pb(ii(at, t++)); 33 | 34 | while(v.size() and (v.rbegin())->se - (v.begin())->se >= k) 35 | v.pop_front(); 36 | } 37 | 38 | int min() { 39 | if(!v.size()) return INF; 40 | return v.begin()->fi; 41 | } 42 | }; 43 | 44 | int main (void) { 45 | ios_base::sync_with_stdio(false); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /data_structures/hld_edge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | O(q * log^2) 3 | Heavy-Light-Decomposition: on edges 4 | 5 | Same thing as in vertices, the cost of an edge is represented 6 | in some vertex v such that edge(u, v, c) and pai[v] = u, so 7 | value(v) = c 8 | 9 | ************* ONE BASED VERTICES *************** 10 | */ 11 | 12 | #include 13 | 14 | using namespace std; 15 | 16 | #define pb push_back 17 | #define mk make_pair 18 | #define fi first 19 | #define se second 20 | 21 | typedef long long ll; 22 | typedef pair ii; 23 | const int INF = 0x3f3f3f3f; 24 | const double PI = acos(-1.0); 25 | 26 | const int N = 1e4 + 5; 27 | int n; 28 | vector g[N], p[N]; 29 | int dist[N], size[N], pai[N]; 30 | int ind, id[N], heavy[N], ch, chain[N], top[N]; 31 | 32 | ll v[N], seg[4*N + 1]; 33 | 34 | void build (int r, int i, int j) { 35 | 36 | if (i == j) { 37 | seg[r] = v[i]; 38 | } else { 39 | int mid = (i + j)/2; 40 | build (2*r, i, mid); 41 | build (2*r + 1, mid + 1, j); 42 | seg[r] = max (seg[2*r], seg[2*r + 1]); 43 | } 44 | } 45 | 46 | int a, b; 47 | ll query (int r, int i, int j, int val) { 48 | if (j < a or i > b) return 0; 49 | 50 | if (i >= a and j <= b) { 51 | if (val != INF) seg[r] = val; 52 | return seg[r]; 53 | } else { 54 | int mid = (i + j)/2; 55 | ll L = query (2*r, i, mid, val); 56 | ll R = query (2*r + 1, mid + 1, j, val); 57 | 58 | seg[r] = max (seg[2*r], seg[2*r + 1]); 59 | return max (L, R); 60 | } 61 | } 62 | 63 | ll update (int l, int r, int val) { 64 | a = l; b = r; 65 | return query (1, 0, n - 1, val); 66 | } 67 | 68 | ll query (int l, int r) { 69 | return update (l, r, INF); 70 | } 71 | 72 | int pre (int at) { 73 | size[at] = 1; 74 | 75 | for (auto next : g[at]) { 76 | if (next == pai[at]) continue; 77 | dist[next] = dist[at] + 1; 78 | pai[next] = at; 79 | 80 | size[at] += pre (next); 81 | 82 | if (size[next] > size[heavy[at]]) 83 | heavy[at] = next; 84 | } 85 | 86 | return size[at]; 87 | } 88 | 89 | void dfs (int at, int pai) { 90 | id[at] = ind++; 91 | 92 | if (heavy[at]) { 93 | chain[heavy[at]] = chain[at]; 94 | dfs (heavy[at], at); 95 | } 96 | 97 | for (auto next : g[at]) { 98 | if (next == pai or next == heavy[at]) continue; 99 | top[ch] = next; 100 | chain[next] = ch++; 101 | dfs (next, at); 102 | } 103 | 104 | for (int i = 0; i < (int)g[at].size(); i++) { 105 | int next = g[at][i]; 106 | int peso = p[at][i]; 107 | if (next == pai) continue; 108 | 109 | v[id[next]] = peso; 110 | } 111 | } 112 | 113 | void build_hld () { 114 | pre (1); 115 | ind = ch = 0; 116 | chain[1] = ch++; 117 | top[0] = 1; 118 | dfs (1, 0); 119 | build (1, 0, n - 1); 120 | } 121 | 122 | ll go (int u, int v) { 123 | ll res = 0; 124 | while (chain[u] != chain[v]) { 125 | if (dist[top[chain[u]]] < dist[top[chain[v]]]) swap (u, v); 126 | 127 | int sobe = top[chain[u]]; 128 | /********* ORDEM: id[sobe] < id[u] ***********/ 129 | res = max (res, query (id[sobe], id[u])); 130 | u = pai[sobe]; 131 | } 132 | if (id[u] > id[v]) swap (u, v); 133 | 134 | res = max (res, query (id[u] + 1, id[v])); 135 | return res; 136 | } 137 | 138 | int main (void) { 139 | 140 | int T; scanf ("%d", &T); 141 | while (T--) { 142 | memset (seg, 0, sizeof seg); 143 | memset (heavy, 0, sizeof heavy); 144 | for (int i = 0; i < N; i++) { 145 | g[i].clear(); 146 | p[i].clear(); 147 | } 148 | cin >> n; 149 | 150 | vector edg; 151 | for (int i = 0; i < n - 1; i++) { 152 | int a, b, c; scanf ("%d %d %d", &a, &b, &c); 153 | g[a].pb(b); p[a].pb(c); 154 | g[b].pb(a); p[b].pb(c); 155 | edg.pb(ii(a,b)); 156 | } 157 | 158 | build_hld (); 159 | 160 | while (1) { 161 | char str[10]; int u, v; 162 | 163 | scanf ("%s", str); 164 | if (str[0] == 'D') break; 165 | 166 | scanf ("%d %d", &u, &v); 167 | 168 | if (str[0] == 'C') { 169 | u--; 170 | int a = edg[u].fi, b = edg[u].se; 171 | if (pai[b] == a) swap (a, b); 172 | update (id[a], id[a], v); 173 | } else { 174 | printf ("%lld\n", go (u, v)); 175 | } 176 | } 177 | } 178 | 179 | return 0; 180 | } 181 | -------------------------------------------------------------------------------- /data_structures/hld_vertex.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | O(n * log^2) 3 | Heavy-Light-Decomposition: on vertices 4 | 5 | ************* ONE BASED VERTICES *************** 6 | */ 7 | 8 | #include 9 | 10 | using namespace std; 11 | 12 | #define pb push_back 13 | #define mk make_pair 14 | #define fi first 15 | #define se second 16 | 17 | typedef long long ll; 18 | typedef pair ii; 19 | const int INF = 0x3f3f3f3f; 20 | const double PI = acos(-1.0); 21 | 22 | const int N = 1e5 + 5; 23 | int n; 24 | vector g[N]; 25 | int dist[N], size[N], pai[N]; 26 | int ind, id[N], heavy[N], ch, chain[N], top[N]; 27 | 28 | ll seg[4*N + 1]; 29 | 30 | int a, b; 31 | ll query (int r, int i, int j, int val) { 32 | if (j < a or i > b) return 0; 33 | 34 | if (i >= a and j <= b) { 35 | return seg[r] += val; 36 | } else { 37 | int mid = (i + j)/2; 38 | ll L = query (2*r, i, mid, val); 39 | ll R = query (2*r + 1, mid + 1, j, val); 40 | 41 | seg[r] = max (seg[2*r], seg[2*r + 1]); 42 | return max (L, R); 43 | } 44 | } 45 | 46 | ll update (int l, int r, int val) { 47 | a = l; b = r; 48 | return query (1, 0, n - 1, val); 49 | } 50 | 51 | ll query (int l, int r) { 52 | return update (l, r, 0); 53 | } 54 | 55 | int pre (int at) { 56 | size[at] = 1; 57 | 58 | for (auto next : g[at]) { 59 | if (next == pai[at]) continue; 60 | dist[next] = dist[at] + 1; 61 | pai[next] = at; 62 | 63 | size[at] += pre (next); 64 | 65 | if (size[next] > size[heavy[at]]) 66 | heavy[at] = next; 67 | } 68 | 69 | return size[at]; 70 | } 71 | 72 | void dfs (int at, int pai) { 73 | id[at] = ind++; 74 | 75 | if (heavy[at]) { 76 | chain[heavy[at]] = chain[at]; 77 | dfs (heavy[at], at); 78 | } 79 | 80 | for (auto next : g[at]) { 81 | if (next == pai or next == heavy[at]) continue; 82 | top[ch] = next; 83 | chain[next] = ch++; 84 | dfs (next, at); 85 | } 86 | } 87 | 88 | void build_hld () { 89 | pre (1); 90 | ind = ch = 0; 91 | chain[1] = ch++; 92 | top[0] = 1; 93 | dfs (1, 0); 94 | } 95 | 96 | ll go (int u, int v) { 97 | ll res = 0; 98 | while (chain[u] != chain[v]) { 99 | if (dist[top[chain[u]]] < dist[top[chain[v]]]) swap (u, v); 100 | 101 | int sobe = top[chain[u]]; 102 | /********* ORDEM: id[sobe] < id[u] ***********/ 103 | res = max (res, query (id[sobe], id[u])); 104 | u = pai[sobe]; 105 | } 106 | if (id[u] > id[v]) swap (u, v); 107 | 108 | res = max (res, query (id[u], id[v])); 109 | return res; 110 | } 111 | 112 | int main (void) { 113 | ios_base::sync_with_stdio(false); 114 | 115 | cin >> n; 116 | 117 | for (int i = 0; i < n - 1; i++) { 118 | int a, b; cin >> a >> b; 119 | g[a].pb(b); 120 | g[b].pb(a); 121 | } 122 | 123 | build_hld (); 124 | 125 | int q; cin >> q; 126 | while (q--) { 127 | char c; int u, v; cin >> c >> u >> v; 128 | if (c == 'I') { 129 | update (id[u], id[u], v); 130 | } else { 131 | cout << go (u, v) << endl; 132 | } 133 | } 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /data_structures/implicit_segtree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | struct node { 16 | node *l, *r; 17 | ll val, lazy; 18 | 19 | node () { 20 | l = r = 0; 21 | val = lazy = 0; 22 | } 23 | }; 24 | 25 | void prop (node *at, int i, int j) { 26 | at->val += at->lazy * (j - i + 1); 27 | 28 | if (i != j) { 29 | if (!at->l) at->l = new node(); 30 | if (!at->r) at->r = new node(); 31 | 32 | at->l->lazy += at->lazy; 33 | at->r->lazy += at->lazy; 34 | } 35 | 36 | at->lazy = 0; 37 | } 38 | 39 | ll query (node *at, int i, int j, int a, int b, int val) { 40 | prop (at, i, j); 41 | if (j < a or i > b) return 0; 42 | 43 | if (i >= a and j <= b) { 44 | at->lazy += val; 45 | prop (at, i, j); 46 | return at->val; 47 | } else { 48 | int mid = (i + j)>>1; 49 | 50 | if (!at->l) at->l = new node(); 51 | if (!at->r) at->r = new node(); 52 | 53 | ll L = query (at->l, i, mid, a, b, val); 54 | ll R = query (at->r, mid + 1, j, a, b, val); 55 | at->val = at->l->val + at->r->val; 56 | return L + R; 57 | } 58 | } 59 | 60 | int main (void) { 61 | ios_base::sync_with_stdio(false); 62 | 63 | int T; cin >> T; 64 | while (T--) { 65 | node *root = new node(); 66 | 67 | int n, q; cin >> n >> q; 68 | 69 | while (q--) { 70 | int c, l, r; cin >> c >> l >> r; 71 | l--; r--; 72 | if (l > r) swap (l, r); 73 | if (c == 0) { 74 | int v; cin >> v; 75 | query (root, 0, n - 1, l, r, v); 76 | } else { 77 | cout << query (root, 0, n - 1, l, r, 0) << endl; 78 | } 79 | } 80 | } 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /data_structures/merge_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | const int N = 250123; 16 | int n; 17 | ii v[N]; 18 | 19 | vector seg[4*N + 1]; 20 | 21 | void build (int r, int i, int j) { 22 | 23 | if (i == j) { 24 | seg[r].pb(v[i].se); 25 | } else { 26 | int mid = (i + j)/2; 27 | build (2*r, i, mid); 28 | build (2*r + 1, mid + 1, j); 29 | 30 | seg[r].resize(j - i + 1); 31 | 32 | merge (seg[2*r].begin(), seg[2*r].end(), 33 | seg[2*r + 1].begin(), seg[2*r + 1].end(), seg[r].begin()); 34 | } 35 | } 36 | 37 | int a, b, c, d; 38 | int query (int r, int i, int j) { 39 | if (v[i].fi > b or v[j].fi < a) return 0; 40 | 41 | if (v[i].fi >= a and v[j].fi <= b) { 42 | 43 | vector &v = seg[r]; 44 | 45 | int i = lower_bound(v.begin(), v.end(), c) - v.begin(); 46 | int j = upper_bound(v.begin(), v.end(), d) - v.begin() - 1; 47 | 48 | return max (0, j - i + 1); 49 | } else { 50 | int mid = (i + j)/2; 51 | int L = query (2*r, i, mid); 52 | int R = query (2*r + 1, mid + 1, j); 53 | return L + R; 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | int w[N]; 60 | 61 | int main (void) { 62 | ios_base::sync_with_stdio(false); 63 | 64 | cin >> n; 65 | 66 | for (int i = 0; i < n; i++) 67 | cin >> v[i].fi >> v[i].se; 68 | sort (v, v + n); 69 | 70 | build (1, 0, n - 1); 71 | 72 | int q; cin >> q; 73 | for (int i = 4; i < q + 4; i++) { 74 | int e, f, g, h; 75 | cin >> e >> f >> g >> h; 76 | 77 | a = e ^ w[i-4]; 78 | b = f ^ w[i-3]; 79 | c = g ^ w[i-2]; 80 | d = h ^ w[i-1]; 81 | 82 | if (a > b) swap (a, b); 83 | if (c > d) swap (c, d); 84 | 85 | w[i] = query (1, 0, n - 1); 86 | 87 | cout << w[i] << endl; 88 | } 89 | 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /data_structures/persistent_seg_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | const int N = 1e5 + 5, M = 3e7 + 7; 16 | int n, a[N]; 17 | int root[N], nodes, L[M], R[M], seg[M]; 18 | 19 | int build (int l, int r) { 20 | int at = ++nodes; 21 | 22 | if (l == r) { 23 | seg[at] = a[at]; 24 | } else { 25 | int m = (l + r)/2; 26 | L[at] = build (l, m); 27 | R[at] = build (m + 1, r); 28 | seg[at] = seg[L[at]] + seg[R[at]]; 29 | } 30 | 31 | return at; 32 | } 33 | 34 | /* point update, v[p]++ */ 35 | int update (int i, int l, int r, int p) { 36 | int at = ++nodes; 37 | 38 | if (l == r) { 39 | seg[at] = seg[i] + 1; 40 | } else { 41 | int m = (l + r)/2; 42 | if (p <= m) { 43 | L[at] = update (L[i], l, m, p); 44 | R[at] = R[i]; 45 | } else { 46 | L[at] = L[i]; 47 | R[at] = update (R[i], m + 1, r, p); 48 | } 49 | seg[at] = seg[L[at]] + seg[R[at]]; 50 | } 51 | 52 | return at; 53 | } 54 | 55 | /* range query: v[A] + ... + v[B] */ 56 | int A, B; 57 | int query (int i, int l, int r) { 58 | if (A > B) return 0; 59 | if (r < A or l > B) return 0; 60 | 61 | if (l >= A and r <= B) { 62 | return seg[i]; 63 | } else { 64 | int m = (l + r)/2; 65 | return query (L[i], l, m) + query (R[i], m + 1, r); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /data_structures/seg2d.cpp: -------------------------------------------------------------------------------- 1 | // LIS2 http://codeforces.com/gym/101055/problem/D SOLUTION 2 | // 3 | // POINT UPDATE, RANGE QUERY 4 | #include 5 | 6 | using namespace std; 7 | 8 | #define pb push_back 9 | #define mk make_pair 10 | #define fi first 11 | #define se second 12 | 13 | typedef long long ll; 14 | typedef pair ii; 15 | const int INF = 0x3f3f3f3f; 16 | const double PI = acos(-1.0); 17 | const double E = exp(1); 18 | 19 | #define L(x) 2*x 20 | #define R(x) 2*x + 1 21 | 22 | struct no { 23 | int *seg; 24 | vector v; 25 | int n; 26 | int ay, by, a, b; 27 | 28 | no () {} 29 | 30 | no (int n) : n(n) { 31 | seg = new int [4*n + 1]; 32 | for (int i = 0; i < 4*n + 1; i++) 33 | seg[i] = 0; 34 | v.resize(n); 35 | } 36 | 37 | int query (int ly, int ry, int l, int r, int val) { 38 | ay = ly; by = ry; 39 | a = l; b = r; 40 | return query (1, 0, n-1, val); 41 | } 42 | 43 | int query (int r, int i, int j, int val) { 44 | if (v[j] < ii(ay, a) or v[i] > ii(by, b)) return 0; 45 | 46 | if (v[i] >= ii(ay, a) and v[j] <= ii(by, b)) { 47 | seg[r] = max (seg[r], val); 48 | return seg[r]; 49 | } else { 50 | int mid = (i + j)/2; 51 | int L = query (L(r), i, mid, val); 52 | int R = query (R(r), mid + 1, j, val); 53 | seg[r] = max (seg[L(r)], seg[R(r)]); 54 | return max(L, R); 55 | } 56 | } 57 | }; 58 | 59 | const int N = 1e5 + 5; 60 | int n; 61 | ii v[N], p[N]; 62 | no seg[4*N + 1]; 63 | 64 | void build (int r, int i, int j) { 65 | seg[r] = no (j - i + 1); 66 | 67 | if (i == j) { 68 | seg[r].v[0] = ii(v[i].se, v[i].fi); 69 | } else { 70 | int mid = (i + j)/2; 71 | build (L(r), i, mid); 72 | build (R(r), mid + 1, j); 73 | 74 | merge (seg[L(r)].v.begin(), seg[L(r)].v.end(), 75 | seg[R(r)].v.begin(), seg[R(r)].v.end(), seg[r].v.begin()); 76 | } 77 | } 78 | 79 | int a, b, ay, by; 80 | 81 | int query (int r, int i, int j, int val) { 82 | if (v[j].fi < a or v[i].fi > b) return 0; 83 | 84 | if (v[i].fi >= a and v[j].fi <= b) { 85 | return seg[r].query(ay, by, a, b, val); 86 | } else { 87 | int mid = (i + j)/2; 88 | int L = query (L(r), i, mid, val); 89 | int R = query (R(r), mid + 1, j, val); 90 | seg[r].query(ay, by, a, b, val); 91 | return max(L, R); 92 | } 93 | } 94 | 95 | int main (void) { 96 | scanf ("%d", &n); 97 | 98 | for (int i = 0; i < n; i++) { 99 | scanf ("%d %d", &p[i].fi, &p[i].se); 100 | v[i] = p[i]; 101 | } 102 | 103 | sort (v, v + n); 104 | build (1, 0, n - 1); 105 | 106 | int res = 0; 107 | /*V DEVE ESTAR ORDENADO PARA AS QUERIES FUNCIONAREM*/ 108 | for (int i = 0; i < n; i++) { 109 | a = 0; b = p[i].fi; 110 | ay = 0; by = p[i].se; 111 | 112 | int x = query (1, 0, n - 1, 0); 113 | 114 | res = max (res, x + 1); 115 | 116 | a = b = p[i].fi; 117 | ay = by = p[i].se; 118 | query (1, 0, n - 1, x + 1); 119 | } 120 | 121 | printf ("%d\n", res); 122 | 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /data_structures/seg_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | struct SegT { 16 | vector seg, lazy; 17 | int n; 18 | 19 | SegT () {} 20 | 21 | SegT (int n) { 22 | this->n = n; 23 | seg.resize(4*n + 1); 24 | lazy.resize(4*n + 1); 25 | } 26 | 27 | void prop (int r, int i, int j) { 28 | 29 | seg[r] += lazy[r] * (j-i+1); 30 | 31 | if (i != j) { 32 | lazy[2*r] += lazy[r]; 33 | lazy[2*r + 1] += lazy[r]; 34 | } 35 | 36 | lazy[r] = 0; 37 | } 38 | 39 | int a, b; 40 | ll update (int r, int i, int j, ll val) { 41 | prop (r, i, j); 42 | if (j < a or i > b) return 0LL; 43 | 44 | if (i >= a and j <= b) { 45 | lazy[r] += val; 46 | prop (r, i, j); 47 | return seg[r]; 48 | } else { 49 | int mid = (i + j)/2; 50 | ll L = update (2*r, i, mid, val); 51 | ll R = update (2*r + 1, mid + 1, j, val); 52 | return L + R; 53 | } 54 | } 55 | 56 | ll update (int l, int r, ll val) { 57 | a = l; b = r; 58 | return update (1, 0, n - 1, val); 59 | } 60 | 61 | ll query (int l, int r) { 62 | return update (l, r, 0); 63 | } 64 | 65 | }; 66 | 67 | int main (void) { 68 | ios_base::sync_with_stdio(false); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /data_structures/sparse_table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | const int N = 1e5 + 5, LOG = 20; 16 | int n, a[N]; 17 | 18 | int lg[N]; 19 | struct SparseTable { 20 | int n, table[N][LOG]; 21 | 22 | SparseTable () {} 23 | 24 | SparseTable (int n) : n(n) { 25 | for (int i = 0; i < n; i++) 26 | table[i][0] = a[i]; 27 | 28 | for (int j = 1; (1< r) swap (l, r); 35 | int tam = r - l + 1; 36 | 37 | return min (table[l][lg[tam]], table[r - (1<> n; 53 | for (int i = 0; i < n; i++) 54 | cin >> a[i]; 55 | st = SparseTable(n); 56 | 57 | int q; cin >> q; 58 | while (q--) { 59 | int l, r; cin >> l >> r; 60 | cout << st.query (l, r) << endl; 61 | } 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /files.json: -------------------------------------------------------------------------------- 1 | { 2 | "solution": ["Alg1/opt.cpp", 3 | "Alg1/opt2.cpp", 4 | "Random/double.cpp"], 5 | "brute": "Brute/a.cpp", 6 | "generator": "generator.cpp" 7 | } 8 | -------------------------------------------------------------------------------- /graph/2_sat_cnf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 SAT 2 CNF O(N + M) 2 | 3 | 2 SAT: 4 | (a V b): 5 | not a => b 6 | not b => a 7 | 8 | 2 CNF: 9 | (a implies b): 10 | a => b 11 | not b => not a 12 | (a implies b): (not a V b) 13 | 14 | OBS: define N as 2*n, n is the number of variables 15 | */ 16 | 17 | #include 18 | 19 | using namespace std; 20 | 21 | #define pb push_back 22 | #define mk make_pair 23 | #define fi first 24 | #define se second 25 | 26 | typedef long long ll; 27 | typedef pair ii; 28 | const int INF = 0x3f3f3f3f; 29 | const double PI = acos(-1.0); 30 | const double E = exp(1); 31 | 32 | const int N = 2e5 + 3; 33 | 34 | bool vis[N]; 35 | int entra[N], sai[N], low[N], comp[N]; 36 | vector g[N]; 37 | stack st; 38 | int ncp, t; 39 | 40 | void init () { 41 | for (int i = 0; i < N; i++) 42 | g[i].clear(); 43 | memset(vis, 0, sizeof vis); 44 | ncp = 0; t = 0; 45 | } 46 | 47 | void dfs (int at) { 48 | vis[at] = true; 49 | entra[at] = low[at] = t++; 50 | st.push(at); 51 | 52 | for (int next : g[at]) 53 | if (!vis[next]) { 54 | dfs(next); 55 | low[at] = min(low[at], low[next]); 56 | } else 57 | low[at] = min(low[at], entra[next]); 58 | 59 | if (low[at] == entra[at]) { 60 | int a; 61 | do { 62 | a = st.top(); st.pop(); 63 | comp[a] = ncp; 64 | entra[a] = INF; 65 | } while (a != at); 66 | ncp++; 67 | } 68 | 69 | sai[at] = t++; 70 | } 71 | 72 | // id x = 2*x 73 | // id not x = 2*x + 1 74 | int id (int x, bool n) { 75 | return 2*x + n; 76 | } 77 | 78 | // na == 0, var: a 79 | // na == 1, var: not a 80 | void add_or (int a, bool na, int b, bool nb) { 81 | g[id(a, !na)].pb(id(b, nb)); 82 | g[id(b, !nb)].pb(id(a, na)); 83 | } 84 | 85 | // na == 0, var: a 86 | // na == 1, var: not a 87 | void add_implies (int a, bool na, int b, bool nb) { 88 | add_or (a, !na, b, nb); 89 | } 90 | 91 | void no () { 92 | cout << "Impossible" << endl; 93 | exit(0); 94 | } 95 | 96 | int n; 97 | int ans[N]; 98 | 99 | int main (void) { 100 | ios_base::sync_with_stdio(false); 101 | 102 | init (); 103 | 104 | for (int i = 0; i < 2*n; i++) 105 | if (!vis[i]) 106 | dfs (i); 107 | 108 | // if comp[x] == comp[not x] there is no answer 109 | // if there is a path from v to w, comp[v] > comp[w] 110 | for (int i = 0; i < n; i++) 111 | if (comp[2*i] == comp[2*i + 1]) 112 | no (); 113 | else if (comp[2*i] < comp[2*i + 1]) 114 | ans[i] = true; 115 | else 116 | ans[i] = false; 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /graph/BellmanFord.cpp: -------------------------------------------------------------------------------- 1 | /* Bellman Ford Algorithm O(VE) */ 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define pb push_back 8 | #define mk make_pair 9 | #define fi first 10 | #define se second 11 | 12 | typedef long long ll; 13 | typedef pair ii; 14 | const int INF = 0x3f3f3f3f; 15 | const double PI = acos(-1.0); 16 | 17 | const int N = 301; 18 | ll dist[N]; 19 | vector g[N], p[N]; 20 | int n; 21 | 22 | void NegativeCicle () { } 23 | 24 | void BellmanFord (int s) { 25 | memset (dist, INF, sizeof dist); 26 | dist[s] = 0; 27 | 28 | for (int i = 0; i < n - 1; i++) 29 | for (int at = 0; at < n; at++) 30 | for (int j = 0; j < (int)g[at].size(); j++) { 31 | ll next = g[at][j], w = p[at][j]; 32 | dist[next] = min (dist[next], dist[at] + w); 33 | } 34 | 35 | 36 | for (int at = 0; at < n; at++) 37 | for (int j = 0; j < (int)g[at].size(); j++) { 38 | ll next = g[at][j], w = p[at][j]; 39 | if (dist[next] > dist[at] + w) 40 | NegativeCicle(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /graph/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | 14 | const int N = 1e5 + 5; 15 | vector g[N], p[N]; 16 | int d[N]; 17 | 18 | ll go (int s, int t) { 19 | for (int i = 0; i < N; i++) d[i] = INF; 20 | priority_queue , greater > pq; 21 | 22 | d[s] = 0; 23 | pq.push(mk(0,s)); 24 | 25 | while (pq.size()) { 26 | int at = pq.top().se; int dist = pq.top().fi; 27 | pq.pop(); 28 | 29 | if (at == t) 30 | return dist; 31 | 32 | for (int i = 0; i < (int)g[at].size(); i++) { 33 | int next = g[at][i], cost = p[at][i]; 34 | if (dist + cost < d[next]) { 35 | d[next] = dist + cost; 36 | pq.push(mk(d[next], next)); 37 | } 38 | } 39 | } 40 | 41 | return -1; 42 | } 43 | 44 | int main (void) { 45 | ios_base::sync_with_stdio(false); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /graph/EdmondsKarp.cpp: -------------------------------------------------------------------------------- 1 | /* O(V * E^2) */ 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define pb push_back 8 | #define mk make_pair 9 | #define fi first 10 | #define se second 11 | 12 | typedef long long ll; 13 | typedef pair ii; 14 | const int INF = 0x3f3f3f3f; 15 | const double PI = acos(-1.0); 16 | const double E = exp(1); 17 | 18 | const int N = 202; 19 | 20 | struct Flow { 21 | public: 22 | int n, m; 23 | int pai[N]; 24 | int flow[N][N], cap[N][N]; 25 | vector g[N]; 26 | 27 | Flow () { 28 | memset (flow, 0, sizeof flow); 29 | memset (cap, 0, sizeof cap); 30 | for (int i = 0; i < N; i++) 31 | g[i].clear(); 32 | } 33 | 34 | void edge (int a, int b, int c) { 35 | g[a].pb(b); 36 | g[b].pb(a); 37 | cap[a][b] += c; 38 | } 39 | 40 | Flow (int n, int m) { 41 | *(this) = Flow (); 42 | this->n = n; this->m = m; 43 | for (int i = 0; i < m; i++) { 44 | int a, b, c; cin >> a >> b >> c; 45 | if (a == b) continue; 46 | edge (a, b, c); 47 | } 48 | } 49 | 50 | void bfs (int s, int t) { 51 | queue q; 52 | q.push(s); 53 | 54 | while (!q.empty()) { 55 | int at = q.front(); q.pop(); 56 | for (int i = 0; i < (int)g[at].size(); i++) { 57 | int next = g[at][i]; 58 | if (cap[at][next] > 0 and pai[next] == -1) { 59 | pai[next] = at; 60 | q.push(next); 61 | if (next == t) return; 62 | } 63 | } 64 | } 65 | 66 | } 67 | 68 | int go (int s, int t) { 69 | while (1) { 70 | memset (pai, -1, sizeof pai); 71 | bfs(s, t); 72 | 73 | if(pai[t] == -1) { 74 | int ret = 0; 75 | for (int i = 0; i <= n; i++) 76 | ret += flow[i][t]; 77 | return ret; 78 | } 79 | 80 | int f = INF; 81 | 82 | for (int at = t; at != s; at = pai[at]) f = min (f, cap[pai[at]][at]); 83 | 84 | for (int at = t; at != s; at = pai[at]) { 85 | flow[pai[at]][at] += f; 86 | cap[pai[at]][at] -= f; 87 | cap[at][pai[at]] += f; 88 | } 89 | } 90 | } 91 | 92 | } F; 93 | 94 | int main (void) { 95 | ios_base::sync_with_stdio(false); 96 | 97 | int n, m, s, t; 98 | while (cin >> n >> m >> s >> t) { 99 | F = Flow (n, m); 100 | cout << F.go(s, t) << endl; 101 | } 102 | 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /graph/EdmondsKarp2.cpp: -------------------------------------------------------------------------------- 1 | /* O (V * E^2) 2 | Implementacao mais facil pra recuperar o flow 3 | * 4 | * MinCut tutorial: 5 | * 6 | * Grafo do flow G 7 | * MinCut: corte de G em S - T, s pertence a S e t pertence a T 8 | * 9 | * MinCut = MaxFlow 10 | * 11 | * Todos os vertices alcancaveis por s no grafo residual final 12 | * pertence a S o resto pertence a T 13 | * 14 | * As arestas de MinCut sao todas que ligam S a T 15 | */ 16 | 17 | #include 18 | 19 | using namespace std; 20 | 21 | #define pb push_back 22 | #define mk make_pair 23 | #define fi first 24 | #define se second 25 | 26 | typedef long long ll; 27 | typedef pair ii; 28 | const int INF = 0x3f3f3f3f; 29 | const double PI = acos(-1.0); 30 | 31 | struct edge { 32 | int to, cap, flow, rid; 33 | 34 | edge () {} 35 | 36 | edge (int a, int b, int c, int d) : 37 | to(a), cap(b), flow(c), rid(d) {} 38 | }; 39 | 40 | const int N = 111; 41 | vector g[N]; 42 | 43 | void add (int a, int b, int c) { 44 | g[a].pb(edge(b, c, 0, g[b].size())); 45 | g[b].pb(edge(a, 0, 0, g[a].size() - 1)); 46 | } 47 | 48 | ii pai[N]; 49 | int bfs (int s, int t) { 50 | for (int i = 0; i < N; i++) 51 | pai[i] = ii(-1, -1); 52 | queue q; 53 | q.push(ii(s, INF)); 54 | 55 | while (!q.empty()) { 56 | int at = q.front().fi; 57 | int free = q.front().se; 58 | q.pop(); 59 | 60 | for (int i = 0 ; i < (int)g[at].size(); i++) { 61 | edge edg = g[at][i]; 62 | if (pai[edg.to].fi == -1 and edg.cap - edg.flow > 0) { 63 | int f = min(edg.cap - edg.flow, free); 64 | q.push(ii(edg.to, f)); 65 | pai[edg.to] = ii(at, i); 66 | if (edg.to == t) 67 | return f; 68 | } 69 | } 70 | } 71 | return 0; 72 | } 73 | 74 | int max_flow (int s, int t) { 75 | int ret = 0; 76 | while (1) { 77 | int f = bfs (s, t); 78 | 79 | if (!f) break; 80 | 81 | for (int at = t; at != s; at = pai[at].fi) { 82 | edge &edg = g[pai[at].fi][pai[at].se]; 83 | edg.flow += f; 84 | 85 | edge &redg = g[edg.to][edg.rid]; 86 | redg.flow -= f; 87 | } 88 | 89 | ret += f; 90 | } 91 | return ret; 92 | } 93 | 94 | bool vis[N]; 95 | void find_MinCut (int at, int s) { 96 | vis[at] = 1; 97 | 98 | for (int i = 0; i < (int)g[at].size(); i++) { 99 | edge edg = g[at][i]; 100 | int next = edg.to; 101 | if (pai[next].fi == -1 and next != s) 102 | cout << at << " " << next << endl; 103 | else if (!vis[next]) 104 | find_MinCut (next, s); 105 | } 106 | } 107 | 108 | int main (void) { 109 | ios_base::sync_with_stdio(false); 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /graph/MaxFlowMinCost.cpp: -------------------------------------------------------------------------------- 1 | /* O(V * E^2 * log(V))*/ 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define pb push_back 8 | #define mk make_pair 9 | #define fi first 10 | #define se second 11 | 12 | typedef long long ll; 13 | typedef pair ii; 14 | const int INF = 0x3f3f3f3f; 15 | const double PI = acos(-1.0); 16 | 17 | struct edge { 18 | int to, cost, cap, flow, rid; 19 | 20 | edge () {} 21 | 22 | edge (int a, int b, int c, int d, int e) : 23 | to(a), cost(b), cap(c), flow(d), rid(e) {} 24 | }; 25 | 26 | const int N = 111; 27 | vector g[N]; 28 | int n; 29 | 30 | void add (int a, int b, int cost, int cap) { 31 | g[a].pb(edge(b, cost, cap, 0, g[b].size())); 32 | g[b].pb(edge(a, -cost, 0, 0, g[a].size() - 1)); 33 | } 34 | 35 | int h[N]; 36 | /*negative edges*/ 37 | void bellman_ford (int s) { 38 | fill (h, h + N, INF); 39 | h[s] = 0; 40 | for (int i = 0; i < n - 1; i++) 41 | for (int at = 0; at < n; at++) 42 | for (int j = 0; j < (int)g[at].size(); j++) { 43 | if (!g[at][j].cap) continue; 44 | int next = g[at][j].to, w = g[at][j].cost; 45 | h[next] = min (h[next], h[at] + w); 46 | } 47 | } 48 | 49 | ii pai[N]; 50 | int dist[N]; 51 | int dijkstra (int s, int t) { 52 | fill (dist, dist + N, INF); 53 | for (int i = 0; i < N; i++) 54 | pai[i] = ii(-1, -1); 55 | priority_queue , greater > pq; 56 | 57 | dist[s] = 0; 58 | pq.push(ii(0, s)); 59 | 60 | bool ret = false; 61 | while (pq.size()) { 62 | int at = pq.top().se; 63 | int d = pq.top().fi; 64 | pq.pop(); 65 | 66 | if (at == t) 67 | ret = true; 68 | 69 | if (d != dist[at]) 70 | continue; 71 | 72 | for (int i = 0; i < (int)g[at].size(); i++) { 73 | edge edg = g[at][i]; 74 | int next = edg.to; 75 | if (edg.cap - edg.flow <= 0) continue; 76 | ll w = dist[at] + edg.cost + h[at] - h[next]; 77 | if (dist[next] > w) { 78 | dist[next] = w; 79 | pai[next] = ii(at, i); 80 | pq.push(ii(dist[next], next)); 81 | } 82 | } 83 | } 84 | 85 | for (int i = 0; i < N; i++) 86 | if (h[i] < INF and dist[i] < INF) 87 | h[i] += dist[i]; 88 | 89 | return ret; 90 | } 91 | 92 | ii max_flow (int s, int t) { 93 | int cost = 0, flow = 0; 94 | bellman_ford(s); 95 | 96 | while (dijkstra(s, t)) { 97 | int f = INF; 98 | for (int at = t; at != s; at = pai[at].fi) { 99 | edge edg = g[pai[at].fi][pai[at].se]; 100 | f = min (f, edg.cap - edg.flow); 101 | } 102 | flow += f; 103 | for (int at = t; at != s; at = pai[at].fi) { 104 | edge &edg = g[pai[at].fi][pai[at].se]; 105 | edg.flow += f; 106 | g[edg.to][edg.rid].flow -= f; 107 | cost += edg.cost * f; 108 | } 109 | } 110 | 111 | return mk(cost, flow); 112 | } 113 | 114 | int main (void) { 115 | ios_base::sync_with_stdio(false); 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /graph/centroid_decomposition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | const int N = 1e5 + 5; 16 | vector g[N]; 17 | int n, sub[N]; 18 | bool cent[N]; 19 | 20 | // Calcula sub 21 | int dfs (int at, int pai) { 22 | sub[at] = 1; 23 | 24 | for (int next : g[at]) { 25 | if (next == pai or cent[next]) continue; 26 | sub[at] += dfs (next, at); 27 | } 28 | 29 | return sub[at]; 30 | } 31 | 32 | // acha centroid 33 | int find_centroid (int at, int pai, int total) { 34 | int mx = 0; 35 | 36 | for (int next : g[at]) { 37 | if (next == pai or cent[next]) continue; 38 | mx = max (sub[next], mx); 39 | } 40 | 41 | if (2*mx <= total) 42 | return at; 43 | 44 | for (int next : g[at]) { 45 | if (next == pai or cent[next]) continue; 46 | if (sub[next] == mx) 47 | return find_centroid (next, at, total); 48 | } 49 | 50 | return -1; 51 | } 52 | 53 | void go (int at) { 54 | int total = dfs (at, -1); 55 | at = find_centroid (at, -1, total); 56 | if (at == -1) return; 57 | cent[at] = 1; 58 | 59 | // centroid eh o at agora 60 | 61 | // vai para as proximas subtrees 62 | for (int next : g[at]) 63 | if (!cent[next]) 64 | go (next); 65 | 66 | cent[at] = 0; 67 | } 68 | 69 | int main (void) { 70 | ios_base::sync_with_stdio(false); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /graph/dfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | const double E = exp(1); 15 | 16 | const int N = 1e3 + 3; 17 | 18 | class Digrafo { 19 | public: 20 | bool vis[N]; 21 | int entra[N], sai[N], low[N], comp[N]; 22 | vector g[N]; 23 | stack st; 24 | int ncp, t; 25 | 26 | Digrafo() { 27 | memset(vis, 0, sizeof vis); 28 | ncp = 0; t = 0; 29 | } 30 | 31 | void dfs (int at) { 32 | vis[at] = true; 33 | entra[at] = low[at] = t++; 34 | st.push(at); 35 | 36 | for (int next : g[at]) 37 | if (!vis[next]) { 38 | dfs(next); 39 | low[at] = min(low[at], low[next]); 40 | } else 41 | low[at] = min(low[at], entra[next]); 42 | 43 | if (low[at] == entra[at]) { 44 | int a; 45 | do { 46 | a = st.top(); st.pop(); 47 | comp[a] = ncp; 48 | entra[a] = INF; 49 | } while (a != at); 50 | ncp++; 51 | } 52 | 53 | sai[at] = t++; 54 | } 55 | }; 56 | 57 | class Grafo { 58 | public: 59 | bool vis[N]; 60 | vector g[N]; 61 | int entra[N], sai[N], low[N]; 62 | int t; 63 | 64 | Grafo () { 65 | memset(vis, 0, sizeof vis); 66 | t = 0; 67 | } 68 | 69 | void ponte (int u, int v) { 70 | 71 | } 72 | 73 | void vertice_corte (int u) { 74 | 75 | } 76 | 77 | void dfs (int at, int pai) { 78 | vis[at] = true; 79 | low[at] = entra[at] = t++; 80 | int filhos = 0; 81 | bool f = false; 82 | 83 | for (int next : g[at]) 84 | if (!vis[next]) { 85 | dfs(next, at); 86 | filhos++; 87 | if (low[next] >= entra[at]) 88 | f = true; 89 | low[at] = min(low[next], low[at]); 90 | if (low[next] > entra[at]) 91 | ponte(at, next); 92 | } else if (next != pai) { 93 | low[at] = min(low[at], entra[next]); 94 | } 95 | 96 | if (pai == -1) { 97 | if (filhos >= 2) vertice_corte(at); 98 | } else 99 | if (f) vertice_corte(at); 100 | 101 | sai[at] = t++; 102 | } 103 | 104 | /*retorna true se v eh ancestral de u*/ 105 | bool ancestral (int v, int u) { 106 | return (entra[v] < entra[u] and sai[u] < sai[v]); 107 | } 108 | }; 109 | 110 | int main (void) { 111 | ios_base::sync_with_stdio(false); 112 | 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /graph/dinic.cpp: -------------------------------------------------------------------------------- 1 | // O(V**2 * E) 2 | // runs fast for bipartide matching 3 | // emaxx implemantation 4 | #include 5 | 6 | #define fi first 7 | #define se second 8 | #define pb push_back 9 | #define eb emplace_back 10 | #define mk make_pair 11 | #define INF 0x3f3f3f3f 12 | 13 | using namespace std; 14 | 15 | typedef long long ll; 16 | typedef pair ii; 17 | 18 | const int N = 4e5 + 5; 19 | const int S = N-2, T = N-1; 20 | 21 | struct edge { 22 | int a, b, cap, flow; 23 | }; 24 | 25 | int d[N], ptr[N], q[N]; 26 | vector e; 27 | vector g[N]; 28 | 29 | void add_edge (int a, int b, int cap) { 30 | edge e1 = { a, b, cap, 0 }; 31 | edge e2 = { b, a, 0, 0 }; 32 | g[a].push_back ((int) e.size()); 33 | e.push_back (e1); 34 | g[b].push_back ((int) e.size()); 35 | e.push_back (e2); 36 | } 37 | 38 | bool bfs(int s, int t) { 39 | int qh=0, qt=0; 40 | q[qt++] = s; 41 | memset (d, -1, sizeof d); 42 | d[s] = 0; 43 | while (qh < qt && d[t] == -1) { 44 | int v = q[qh++]; 45 | for (size_t i=0; i 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | const int N = 401; 8 | const ll INF = 0x3f3f3f3f; 9 | 10 | int adj[N][N]; 11 | int v; 12 | 13 | void floyd () { 14 | for (int k = 0; k < v; k++) 15 | for (int i = 0; i < v; i++) 16 | for (int j = 0; j < v; j++) 17 | adj[i][j] = min(adj[i][j], adj[i][k] + adj[k][j]); 18 | 19 | } 20 | 21 | int main (void) { 22 | memset(adj, INF, sizeof adj); 23 | // Ler adj 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /graph/kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef pair ii; 11 | const int INF = 0x3f3f3f3f; 12 | const double PI = acos(-1.0); 13 | const double E = exp(1); 14 | 15 | const int N = 1e5 + 4; 16 | 17 | class uni { 18 | public: 19 | int pai[N], size[N]; 20 | int cps; 21 | 22 | uni() { 23 | memset(pai, -1, sizeof pai); 24 | for(int i = 0; i < N; i++) 25 | size[i] = 1; 26 | } 27 | 28 | uni(int n) { 29 | memset(pai, -1, sizeof pai); 30 | for(int i = 0; i < N; i++) 31 | size[i] = 1; 32 | cps = n; 33 | } 34 | 35 | int find (int u) { 36 | if (pai[u] == -1) 37 | return u; 38 | else 39 | return pai[u] = find(pai[u]); 40 | } 41 | 42 | bool une (int u, int v) { 43 | u = find(u); v = find(v); 44 | if (u == v) return false; 45 | 46 | if (size[u] < size[v]) 47 | swap(u, v); 48 | 49 | pai[v] = u; 50 | size[u] += size[v]; 51 | size[v] = 0; 52 | cps--; 53 | return true; 54 | } 55 | 56 | int comps () { return cps; } 57 | }; 58 | 59 | vector > edg; 60 | vector mst; 61 | 62 | int kruskal () { 63 | sort(edg.begin(), edg.end()); 64 | int ret = 0; 65 | uni U; 66 | 67 | for (int i = 0; i < (int)edg.size(); i++) { 68 | int u = edg[i].se.fi, v = edg[i].se.se; 69 | int dist = edg[i].fi; 70 | if (U.une(u,v)) { 71 | mst.pb(mk(u,v)); 72 | ret += dist; 73 | } 74 | } 75 | 76 | return ret; 77 | } 78 | 79 | int main (void) { 80 | ios_base::sync_with_stdio(false); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /graph/kuhn.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | const int N = 512; 16 | int n; 17 | int mt[N], nt[N]; 18 | bool vis[N]; 19 | vector g[N]; 20 | 21 | bool kuhn (int at) { 22 | if (vis[at]) return false; 23 | vis[at] = 1; 24 | 25 | for (auto next : g[at]) 26 | if (mt[next] == -1) { 27 | mt[next] = at; 28 | nt[at] = next; 29 | return true; 30 | } 31 | 32 | for (auto next : g[at]) 33 | if (kuhn(mt[next])) { 34 | mt[next] = at; 35 | nt[at] = next; 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | 42 | int max_matching () { 43 | memset (mt, -1, sizeof mt); 44 | memset (nt, -1, sizeof nt); 45 | 46 | int mm = 0; 47 | 48 | for (int i = 0; i < n; i++) { 49 | memset (vis, 0, sizeof vis); 50 | 51 | mm += kuhn (i); 52 | } 53 | 54 | return mm; 55 | } 56 | 57 | int main (void) { 58 | ios_base::sync_with_stdio(false); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /graph/kuhn2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | const int N = 1e4 + 4; 16 | int n; 17 | int mt[N], nt[N]; 18 | bool vis[N]; 19 | vector g[N]; 20 | 21 | bool kuhn (int at) { 22 | if (vis[at]) return false; 23 | vis[at] = 1; 24 | 25 | for (auto next : g[at]) 26 | if (mt[next] == -1) { 27 | mt[next] = at; 28 | nt[at] = next; 29 | return true; 30 | } 31 | 32 | for (auto next : g[at]) 33 | if (kuhn(mt[next])) { 34 | mt[next] = at; 35 | nt[at] = next; 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | 42 | int max_matching () { 43 | memset (mt, -1, sizeof mt); 44 | memset (nt, -1, sizeof nt); 45 | 46 | int mm = 0; 47 | 48 | bool updated = true; 49 | while (updated) { 50 | updated = false; 51 | memset (vis, 0, sizeof vis); 52 | 53 | for (int i = 0; i < n; i++) 54 | if (nt[i] == -1 and kuhn(i)) { 55 | mm ++; 56 | updated = true; 57 | } 58 | } 59 | 60 | return mm; 61 | } 62 | 63 | int main (void) { 64 | ios_base::sync_with_stdio(false); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /graph/lca.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | const double E = exp(1); 15 | 16 | const int N = 1e5 + 5; 17 | const int LOG = 20; 18 | vector g[N]; 19 | 20 | class LCA { 21 | public: 22 | int pai[N][LOG], dist[N]; 23 | 24 | void build (int curr){ 25 | for (int i = 1; i < LOG; i++){ 26 | pai[curr][i] = pai[pai[curr][i-1]][i-1]; 27 | } 28 | } 29 | 30 | void ini (int curr, int last, int d){ 31 | dist[curr] = d; 32 | pai[curr][0] = last; 33 | build (curr); 34 | 35 | for (unsigned int i = 0; i < g[curr].size(); i++){ 36 | int next = g[curr][i]; 37 | if (next != last) ini (next, curr, d+1); 38 | } 39 | } 40 | 41 | 42 | int query (int u, int v){ 43 | if (dist[v] < dist[u]) 44 | swap(v,u); 45 | 46 | int x = dist[v] - dist[u]; 47 | 48 | for (int i = 0; i < LOG; i++) 49 | if (x & (1<= 0; i--) 55 | if (pai[u][i] != pai[v][i]) { 56 | u = pai[u][i]; 57 | v = pai[v][i]; 58 | } 59 | 60 | return pai[u][0]; 61 | } 62 | }; 63 | 64 | -------------------------------------------------------------------------------- /int128.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define eb emplace_back 7 | #define mk make_pair 8 | #define fi first 9 | #define se second 10 | 11 | typedef long long ll; 12 | typedef __int128 LL; 13 | typedef pair ii; 14 | const int INF = 0x3f3f3f3f; 15 | const double PI = acos(-1.0); 16 | 17 | LL read() { 18 | LL x = 0, f = 1; 19 | char ch = getchar(); 20 | while (ch < '0' || ch > '9') { 21 | if (ch == '-') f = -1; 22 | ch = getchar(); 23 | } 24 | while (ch >= '0' && ch <= '9') { 25 | x = x * 10 + ch - '0'; 26 | ch = getchar(); 27 | } 28 | return x * f; 29 | } 30 | 31 | void print(LL x) { 32 | if (x < 0) { 33 | putchar('-'); 34 | x = -x; 35 | } 36 | if (x > 9) print(x / 10); 37 | putchar(x % 10 + '0'); 38 | } 39 | 40 | int main (void) { 41 | ios_base::sync_with_stdio(false); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /judge.py: -------------------------------------------------------------------------------- 1 | # github.com/guitubone 2 | # Samuel Ferreira 3 | # github.com/LoppA 4 | 5 | import os 6 | import sys 7 | 8 | wa = -1 9 | 10 | for i in range (1, 285) : 11 | file_name = 'K_' + str(i); 12 | input_file = 'input/' + file_name 13 | output_file = 'output/' + file_name 14 | if (os.path.isfile(input_file)) : 15 | cmd = './a.out <' + input_file + ' >out' 16 | os.system(cmd) 17 | cmd = 'diff ' + output_file + ' out >diff' 18 | os.system(cmd) 19 | print ('Judging test case ' + str(i)) 20 | if (os.stat("diff").st_size != 0) : 21 | if (wa == -1) : 22 | wa = i 23 | print ('\tNO') 24 | else : 25 | print ('\tOK') 26 | 27 | print("\n-----------------------------------------\n") 28 | if (wa == -1) : 29 | print("ACCEPTED!") 30 | else: 31 | print("WA on test case " + str(wa)) 32 | print("\n-----------------------------------------\n") 33 | -------------------------------------------------------------------------------- /math/EulerTotient.cpp: -------------------------------------------------------------------------------- 1 | // https://codeforces.com/blog/entry/106851 2 | // phi(p^k) = p^k - p^(k-1) 3 | // If gcd(a,b) = 1 then phi(a*b) = phi(a) * phi(b) 4 | // 5 | // Factorizing n, n = p1^e1 * p2^e2 ... pk^ek 6 | // p(n) = phi(p1^e1) * phi(p2^e2) ... phi(pk^ek) 7 | // p(n) = (p1^e1 - p1^(e1-1)) * (p2^e2 - p2^(e2-1)) ... (pk^ek - pk^(ek-1)) 8 | 9 | #include 10 | 11 | using namespace std; 12 | 13 | #define pb push_back 14 | #define eb emplace_back 15 | #define mk make_pair 16 | #define fi first 17 | #define se second 18 | 19 | typedef long long ll; 20 | typedef pair ii; 21 | const int INF = 0x3f3f3f3f; 22 | const double PI = acos(-1.0); 23 | 24 | // Phi for a single value n 25 | // phi(n) in O(sqrt(n)), bottleneck is factorization, Pollard rho can optimize. 26 | namespace SingleValuePhi { 27 | vector factorize(int n) { 28 | vector v; 29 | int m = sqrt(n); 30 | 31 | for (int i = 2; i <= m; i++) { 32 | if (n%i == 0) { 33 | v.eb(i, 0); 34 | while(n%i == 0) { 35 | n /= i; 36 | v.back().se++; 37 | } 38 | } 39 | } 40 | 41 | if (n > 1) { 42 | v.eb(n,1); 43 | } 44 | 45 | return v; 46 | } 47 | 48 | int getPhi(int n) { 49 | vector divisors = factorize(n); 50 | 51 | int ans = 1; 52 | for (auto [prime, exp] : divisors) { 53 | int power = 1; 54 | for (int i = 1; i < exp; i++) { 55 | power *= prime; 56 | } 57 | ans *= (power * prime - power); // p^exp - p^(exp-1) 58 | } 59 | 60 | return ans; 61 | } 62 | } 63 | 64 | // Batch phi calculation, calculate from 1 to N-1 in O(n*log(n)) 65 | // phi(n) = (p1^e1 - p1^(e1-1)) * (p2^e2 - p2^(e2-1)) ... (pk^ek - pk^(ek-1)) 66 | // Above formula can be written as: 67 | // phi(n) = n * (1 - 1/p1) * (1 - 1/p2) ... * (1 - 1/pk) 68 | // O(n*log(n)), can be optimize with linear sieve. 69 | namespace BatchPhi { 70 | const int N = 5e6 + 5; 71 | int phi[N]; 72 | void build() { 73 | for (int i = 1; i < N; i++) { 74 | phi[i] = i; 75 | } 76 | 77 | for (int i = 2; i < N; i++) { 78 | if (phi[i] == i) { 79 | for (int j = i; j < N; j+=i) { 80 | phi[j] -= phi[j]/i; 81 | } 82 | } 83 | } 84 | } 85 | } 86 | 87 | // phi(n) = (p1^e1 - p1^(e1-1)) * (p2^e2 - p2^(e2-1)) ... (pk^ek - pk^(ek-1)) 88 | // phi(n) = (p^e - p^(e-1)) * phi(n/(p^e)) 89 | // 90 | // If n = i*p, p being the smallest prime that divides n 91 | // If i and p are coprimes => phi(n) = phi(p) * phi(i) 92 | // If p divides i => phi(n) = p * phi(i) 93 | // Because phi(n) = (p^e - p^(e-1)) * phi(n/(p^e)) 94 | // phi(n) = p * (p^(e-1) - p^(e-2)) * phi(n/p^e) 95 | // phi(n) = p * phi(n/p^e) 96 | // O(n), using linear sieve. 97 | namespace LinearBatchPhi { 98 | const int N = 5e6 + 5; 99 | vector prime; 100 | int phi[N]; 101 | 102 | void build() { 103 | for (int i = 1; i < N; i++) { 104 | phi[i] = i; 105 | } 106 | 107 | for (int i = 2; i < N; i++) { 108 | if (phi[i] == i) { 109 | prime.pb(i); 110 | phi[i] = i-1; 111 | } 112 | for (int j = 0; j < (int)prime.size() and i*prime[j] < N; j++) { 113 | if (i%prime[j]) { 114 | phi[i*prime[j]] = phi[i] * phi[prime[j]]; 115 | } else { 116 | phi[i*prime[j]] = prime[j] * phi[i]; 117 | break; // we know that i * prime[j + 1] will also have prime[j] 118 | } 119 | } 120 | } 121 | } 122 | } 123 | 124 | int main (void) { 125 | ios_base::sync_with_stdio(false); 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /math/Fibbonacci_MatrixExpo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | n >= k 4 | 5 | T(n) = a1*T(n-1) + a2*T(n-2) + ... + ak*T(n-k) 6 | 7 | _ _ _ (n-(k-1)) _ _ 8 | | Tn | |a1 ... ak| |Tk-1| 9 | |Tn-1| |1 0 0 0 0| |Tk-2| 10 | |Tn-2| = |0 1 0 0 0| * |Tk-3| 11 | | ...| | ... | | ...| 12 | |_T1_| |0 0 0 1 0| |_T0_| 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | #define mk make_pair 21 | #define fi first 22 | #define se second 23 | 24 | typedef long long ll; 25 | const ll mod = 1e9 + 7; 26 | 27 | class mat { 28 | public: 29 | ll m[2][2]; 30 | 31 | /* 32 | * 1 0 33 | * 0 1 34 | * */ 35 | mat () { 36 | m[0][0] = 1; 37 | m[0][1] = 0; 38 | m[1][0] = 0; 39 | m[1][1] = 1; 40 | } 41 | 42 | /* 43 | * a b 44 | * c d 45 | * */ 46 | mat (ll a, ll b, ll c, ll d) { 47 | m[0][0] = a; 48 | m[0][1] = b; 49 | m[1][0] = c; 50 | m[1][1] = d; 51 | } 52 | 53 | mat operator * (const mat &B) const { 54 | mat ret = mat(0,0,0,0); 55 | for (int i = 0; i < 2; i++) { 56 | for (int j = 0; j < 2; j++) { 57 | for (int k = 0; k < 2; k++) { 58 | ret.m[i][j] += (m[i][k] * B.m[k][j])%mod; 59 | ret.m[i][j] %= mod; 60 | } 61 | } 62 | } 63 | return ret; 64 | } 65 | 66 | }; 67 | 68 | /* 69 | A = 1 1 70 | 1 0 71 | 72 | Fn = A^(n-1) * 1 73 | Fn-1 1 74 | */ 75 | mat exp (ll y) { 76 | mat R, A = mat(1,1,1,0); 77 | mat T = A; 78 | 79 | while (y) { 80 | if ((y & 1)) { 81 | R = R * T; 82 | } 83 | T = T * T; 84 | y >>= 1; 85 | } 86 | 87 | return R; 88 | } 89 | 90 | /* 91 | F(0) = 1 F(1) = 1 92 | F(n) = 1*F(n-1) + 1*F(n-2) 93 | */ 94 | 95 | int main (void) { 96 | 97 | ll n; 98 | while (cin >> n) { 99 | mat f = exp(max(n-1,0LL)); 100 | 101 | ll res = f.m[0][0] + f.m[0][1]; 102 | 103 | cout << "F(" << n << "): "<< res << endl; 104 | } 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /math/LinearSieve.cpp: -------------------------------------------------------------------------------- 1 | // https://codeforces.com/blog/entry/54090 2 | // A composite number q, can be written as 3 | // q = i*p, where p is the smallest prime that divides it. 4 | // From that we know 5 | // 1. i >= p 6 | // 2. Any prime < p can't divide i 7 | #include 8 | 9 | using namespace std; 10 | 11 | #define pb push_back 12 | #define eb emplace_back 13 | #define mk make_pair 14 | #define fi first 15 | #define se second 16 | 17 | typedef long long ll; 18 | typedef pair ii; 19 | const int INF = 0x3f3f3f3f; 20 | const double PI = acos(-1.0); 21 | 22 | const int N = 1e6 + 6; 23 | vector p; 24 | bool vis[N]; 25 | 26 | void sieve() { 27 | for (int i = 2; i < N; i++) { 28 | if (!vis[i]) p.pb(i); 29 | for (int j = 0; j < p.size() and i*p[j] < N; j++) { 30 | vis[i*p[j]] = true; 31 | if (i%p[j]==0) break; // we know that i * prime[j + 1] will also have prime[j] as the smallest prime divisor. 32 | } 33 | } 34 | } 35 | 36 | // A function is a multiplicative function if for p and q coprimes, func(p*q) = func(p) * func(q) 37 | // Example bellow: func(p^k) = k 38 | // cnt[n] counts how many times the smallest prime p divides n. 39 | namespace multiplicativeFunction { 40 | const int N = 5e6 + 6; 41 | vector prime; 42 | bool vis[N]; 43 | int func[N], cnt[N]; 44 | 45 | void sieve () { 46 | func[1] = 1; 47 | for (int i = 2; i < N; ++i) { 48 | if (!vis[i]) { 49 | prime.pb(i); 50 | func[i] = 1; 51 | cnt[i] = 1; 52 | } 53 | for (int j = 0; j < prime.size () && i * prime[j] < N; j++) { 54 | vis[i * prime[j]] = true; 55 | if (i % prime[j] == 0) { 56 | func[i * prime[j]] = func[i] / cnt[i] * (cnt[i] + 1); 57 | cnt[i * prime[j]] = cnt[i] + 1; 58 | break; 59 | } else { 60 | func[i * prime[j]] = func[i] * func[prime[j]]; 61 | cnt[i * prime[j]] = 1; 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | int main (void) { 69 | ios_base::sync_with_stdio(false); 70 | sieve(); 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /math/Makefile_brute: -------------------------------------------------------------------------------- 1 | test: 2 | g++ Karatsuba/a.cpp -Wall -O2 3 | g++ a.cpp -o gen -Wall -O2 4 | $(MAKE) t 5 | 6 | t: 7 | ./gen >testin 8 | ./a.out 5 | 6 | using namespace std; 7 | 8 | #define pb push_back 9 | #define mk make_pair 10 | #define fi first 11 | #define se second 12 | 13 | typedef long long ll; 14 | typedef pair ii; 15 | const int INF = 0x3f3f3f3f; 16 | const double PI = acos(-1.0); 17 | 18 | ll gcd (ll a, ll b) { 19 | if (!b) 20 | return a; 21 | else 22 | return gcd(b, a%b); 23 | } 24 | 25 | // O(sqrt(m)) 26 | // Find x in: a**x = b (mod m) 27 | // a and m are coprimes 28 | // x = np - q => a**(np - q) = b => a**np = b*(a**q) // make n=sqrt(m) 29 | // Find smallest x 30 | ll go(ll a, ll b, ll m) { 31 | a%=m; 32 | b%=m; 33 | if (b == 1) return 0; 34 | 35 | // PARTE DISNEY 36 | if (gcd(a,m) != 1) { 37 | set s; 38 | ll at = a; 39 | for (int i = 1; ; i++) { 40 | if (at == b) return i; 41 | if (s.count(at)) return -1; 42 | s.insert(at); 43 | at = (at * a)%m; 44 | } 45 | } 46 | 47 | // CERTO DAQUI P BAIXO 48 | 49 | ll n = sqrt(m) + 1; 50 | 51 | ll an = 1; 52 | for (int i = 0; i < n; i++) 53 | an = (an * a)%m; 54 | 55 | unordered_map mp; 56 | // b*(a**q) 57 | for (ll i = 0, val = b; i < n; i++, val = (val*a)%m) 58 | mp[val] = i; 59 | 60 | // a**np 61 | for (ll i = 1, val=an; i <= n; i++, val = (val*an)%m) 62 | if (mp.count(val)) { 63 | // cout << a << "**" << n*i - mp[val] << " = " << b << " mod " << m << endl; 64 | // cout << i << " " << val << " " << mp[val] << " " << n << endl; 65 | return n*i - mp[val]; 66 | } 67 | 68 | return -1; 69 | } 70 | 71 | int main (void) { 72 | ios_base::sync_with_stdio(false); 73 | 74 | ll x, z, k; 75 | while (cin >> x >> z >> k and (x+z+k)) { 76 | ll ans = go(x,k,z); 77 | if (ans == -1) 78 | cout << "No Solution" << endl; 79 | else 80 | cout << ans << endl; 81 | } 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /math/combinatorics.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define eb emplace_back 7 | #define mk make_pair 8 | #define fi first 9 | #define se second 10 | 11 | typedef long long ll; 12 | typedef pair ii; 13 | const int INF = 0x3f3f3f3f; 14 | const double PI = acos(-1.0); 15 | 16 | const ll mod = 1e9 + 7; 17 | const int N = 3e5 + 5; 18 | ll fat[N]; 19 | 20 | ll pot(ll x, ll y) { 21 | if(!y) return 1LL; 22 | 23 | ll ret = pot(x, y>>1); 24 | ret = (ret * ret)%mod; 25 | if(y&1) 26 | ret = (ret*x)%mod; 27 | return ret; 28 | } 29 | 30 | // Iterative version 31 | ll i_pot (ll x, ll y) { 32 | ll ret = 1; 33 | 34 | while (y) { 35 | if (y & 1) 36 | ret = (ret * x)%mod; 37 | 38 | x = (x * x)%mod; 39 | y >>= 1; 40 | } 41 | 42 | return ret; 43 | } 44 | 45 | // Formula: n! / (n-k)! * (k)! 46 | // With dinamic programming we can use (n + 1, k) = (n, k-1) + (n, k) and (n, 0) = 1, (n, n) = 1 for n >= 0 47 | // (n, k) = (n, n - k) for 0 <= k <= n 48 | // (n, k) = (n/k) * (n-1, k-1) 49 | ll choose(ll n, ll k) { 50 | if(k > n) return 0LL; 51 | 52 | ll ret = (fat[n] * pot(fat[n-k], mod-2))%mod; 53 | 54 | return (ret * pot(fat[k], mod-2))%mod; 55 | } 56 | 57 | // Stirling Number of The Second Kind: Calculates the number of ways to partition a set of n objects into k non-empty subsets 58 | // Formula explanation: https://math.stackexchange.com/questions/550256/stirling-numbers-of-second-type 59 | // O(k*log2(mod)) 60 | // With dinamic programming we can use S(n + 1, k) = S(n, k - 1) + k*S(n, k) and S(n,n) = 1, S(n, 1) = 1 for n >= 1 61 | ll stirling2(ll n, ll k) { 62 | if(k > n) return 0LL; 63 | 64 | ll ret = 0; 65 | 66 | for(ll j = 0; j <= k; j++) { 67 | ret += pot(-1, j%2) * (choose(k,j) * pot(k-j, n))%mod; 68 | ret %= mod; 69 | } 70 | 71 | ret = (ret * pot(fat[k], mod - 2))%mod; 72 | 73 | if(ret < 0) 74 | return ret + mod; 75 | return ret; 76 | } 77 | 78 | int main (void) { 79 | ios_base::sync_with_stdio(false); 80 | 81 | fat[0] = 1; 82 | for(ll i = 1; i < N; i++) 83 | fat[i] = (fat[i-1] * i)%mod; 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /math/crt.cpp: -------------------------------------------------------------------------------- 1 | // Chinese Remainder Theorem 2 | #include 3 | 4 | using namespace std; 5 | 6 | #define pb push_back 7 | #define eb emplace_back 8 | #define mk make_pair 9 | #define fi first 10 | #define se second 11 | 12 | typedef long long ll; 13 | typedef pair ii; 14 | const int INF = 0x3f3f3f3f; 15 | const double PI = acos(-1.0); 16 | 17 | // ax + by = g 18 | // g = 1 for a and b coprimes 19 | ll gcd(ll a, ll b, ll &x, ll &y) { 20 | if(!b) { 21 | x = 1; 22 | y = 0; 23 | return a; 24 | } 25 | ll ret = gcd(b, a%b, x, y); 26 | ll t = x; 27 | x = y; 28 | y = t - (a/b)*y; 29 | return ret; 30 | } 31 | 32 | const ll mul(ll x, ll y, ll mod) { 33 | ll ret = 0; 34 | 35 | if(x<0) x+= mod; 36 | if(y<0) y+= mod; 37 | 38 | while(y) { 39 | if(y&1) 40 | ret = (ret+x)%mod; 41 | x = (x<<1)%mod; 42 | y >>= 1; 43 | } 44 | 45 | return ret; 46 | } 47 | 48 | inline ll mul(ll a, ll b, ll c, ll mod) { 49 | a %= mod; 50 | b %= mod; 51 | c %= mod; 52 | ll x = mul(a, b, mod); 53 | return mul(x, c, mod); 54 | } 55 | 56 | ll go(ll a0, ll p0, ll a1, ll p1) { 57 | ll m0, m1; 58 | gcd(p0, p1, m0, m1); 59 | 60 | assert(p0*m0 + p1*m1 == 1); 61 | 62 | return mul(a0, p1, m1, (p0*p1)) + mul(a1, p0, m0,(p0*p1)); 63 | } 64 | 65 | ll crt(const vector &a, const vector &p) { 66 | assert(a.size() == p.size()); 67 | int n = a.size(); 68 | 69 | ll _a = a[0]; 70 | ll _p = p[0]; 71 | 72 | for(int i = 1; i < n; i++) { 73 | _a = go(_a, _p, a[i], p[i]); 74 | _p *= p[i]; 75 | _a %= _p; 76 | if(_a < 0) _a += _p; 77 | } 78 | 79 | return _a; 80 | } 81 | 82 | int main (void) { 83 | ios_base::sync_with_stdio(false); 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /math/extended_euclidean.cpp: -------------------------------------------------------------------------------- 1 | /* O(log2(min(a, b))) 2 | Solve ax + by = gcd(a,b) 3 | 4 | Bezouts lemma: there is alwayas a solution 5 | |x| <= |b/g| and |y| <= |a/g| 6 | 7 | x * y <= 0 (x > 0 => y <= 0, y > 0 => x <= 0) 8 | 9 | others solutions: x' = x+k*(b/g), y' = y-k*(a/g) k is integer 10 | 11 | Quick explanation: 12 | r[0] = a, r[1] = b 13 | 14 | 1: r[i-2] = r[i-1]*q[i] + r[i] // gcd algorithm 15 | 2: r[i] = s[i]*a + t[i]*b // we want it 16 | 17 | with 1 and 2: 18 | s[i] = s[i-2] * s[i-1]*q[i] 19 | t[i] = t[i-2] * s[i-1]*q[i] 20 | 21 | r[0] = a = s[0]*a + t[0]*b => s[0] = 1, t[0] = 0 22 | r[1] = b = s[1]*a + t[1]*b => s[1] = 0, t[1] = 1 23 | 24 | algorithm stops at a = g, b = 0 => r[n-2], r[n-1]=0 25 | find gcd(a, b) = r[n-2] = s[n-2]*a + t[n-2]*b 26 | * */ 27 | 28 | #include 29 | 30 | using namespace std; 31 | 32 | #define pb push_back 33 | #define eb emplace_back 34 | #define mk make_pair 35 | #define fi first 36 | #define se second 37 | 38 | typedef long long ll; 39 | typedef pair ii; 40 | const int INF = 0x3f3f3f3f; 41 | const double PI = acos(-1.0); 42 | 43 | // ax + by = g 44 | ll gcd(ll a, ll b, ll &x, ll &y) { 45 | if(!b) { 46 | x = 1; 47 | y = 0; 48 | return a; 49 | } 50 | ll ret = gcd(b, a%b, x, y); 51 | ll t = x; 52 | x = y; 53 | y = t - (a/b)*y; 54 | return ret; 55 | } 56 | 57 | int main (void) { 58 | ios_base::sync_with_stdio(false); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /math/fft.cpp: -------------------------------------------------------------------------------- 1 | /* emaxx implementation */ 2 | /* Multiplication with arbitrary modulos 3 | * use ntt if mod is prime and can be written as 2**k * c + 1 4 | * if not, use Chinese Reminder Theorem 5 | * or transform A(x) = A1(x) + A2(x)*c decompose into A(x)/c and A(x)%c 6 | * B(x) = B1(x) + B2(x)*c 7 | * where c ~= sqrt(mod) 8 | * A * B = A1*B1 + c*(A1*B2 + A2*B1) + c**2(A2*B2) 9 | * with all values < sqrt(mod) subpolynomials have coefficientes < mod * N after fft multiply decreasing changes of rounding error 10 | * */ 11 | 12 | #include 13 | #define pb push_back 14 | 15 | using namespace std; 16 | 17 | const double PI=acos(-1); 18 | 19 | typedef complex base; 20 | 21 | void fft (vector & a, bool invert) { 22 | int n=(int) a.size(); 23 | for (int i=1, j=0; i>1; 25 | for (;j>=bit;bit>>=1) 26 | j-=bit; 27 | j+=bit; 28 | if(i coefs to multiply, res => resulting coefs 50 | // a[0], b[0], res[0] = coef x^0 51 | // Doesnt work with negative coefs 52 | void multiply (const vector & a, const vector & b, vector & res) { 53 | vector fa (a.begin(), a.end()), fb (b.begin(), b.end()); 54 | size_t n=1; 55 | while (n 3 | 4 | using namespace std; 5 | 6 | #define pb push_back 7 | #define eb emplace_back 8 | #define mk make_pair 9 | #define fi first 10 | #define se second 11 | 12 | typedef long long ll; 13 | typedef pair ii; 14 | const int INF = 0x3f3f3f3f; 15 | const double PI = acos(-1.0); 16 | 17 | const int N = 500; 18 | const double EPS = 1e-9; 19 | 20 | // O(n*m*min(n,m)) 21 | int gauss (vector < vector > a, vector & ans) { 22 | int n = (int) a.size(); 23 | int m = (int) a[0].size() - 1; 24 | 25 | vector where (m, -1); 26 | for (int col=0, row=0; col abs (a[sel][col])) 30 | sel = i; 31 | if (abs (a[sel][col]) < EPS) 32 | continue; 33 | for (int i=col; i<=m; ++i) 34 | swap (a[sel][i], a[row][i]); 35 | where[col] = row; 36 | 37 | for (int i=0; i EPS) 55 | return 0; 56 | } 57 | 58 | for (int i=0; i > a, int n, int m, bitset & ans) { 66 | vector where (m, -1); 67 | for (int col=0, row=0; col 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | ll gcd (ll a, ll b) { 8 | if (!b) 9 | return a; 10 | return gcd(b, a%b); 11 | } 12 | -------------------------------------------------------------------------------- /math/geometry/convex_hull.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define mk make_pair 6 | #define pb push_back 7 | #define fi first 8 | #define se second 9 | 10 | typedef pair ii; 11 | typedef long long ll; 12 | const double EPS = 1e-9; 13 | const double PI = acos(-1.0); 14 | 15 | template 16 | class Point { 17 | public: 18 | T x, y; 19 | 20 | Point () { } 21 | 22 | Point (T x, T y) : x(x), y(y) {} 23 | 24 | bool operator == (const Point &b) const { 25 | return (abs (x - b.x) < EPS and abs (y - b.y) < EPS); 26 | } 27 | 28 | bool operator < (const Point &b) const { 29 | return ((x < b.x) or ((x == b.x) and y < b.y)); 30 | } 31 | 32 | T operator ^ (const Point &b) const { 33 | return (this->x * b.y) - (this->y * b.x); 34 | } 35 | 36 | T operator * (const Point &b) const { 37 | return (this->x * b.x) + (this->y * b.y); 38 | } 39 | 40 | Point operator * (T k) const { 41 | return Point (x*k, y*k); 42 | } 43 | 44 | Point operator / (T k) const { 45 | return Point (x/k, y/k); 46 | } 47 | 48 | Point operator + (const Point &b) const { 49 | return Point (x + b.x, y + b.y); 50 | } 51 | 52 | Point operator - (const Point &b) const { 53 | return Point (x - b.x, y - b.y); 54 | } 55 | 56 | T len2 () const { 57 | return x*x + y*y; 58 | } 59 | 60 | T len () const { 61 | return sqrt (x*x + y*y); 62 | } 63 | 64 | T dpp2 (const Point &b) const { 65 | return ((*this)-b)*((*this)-b); 66 | } 67 | 68 | T dpp (const Point &b) const { 69 | return ((*this)-b).len(); 70 | } 71 | 72 | /* return counter clock points of convex hull 73 | * WITHOUT COLINEAR POINTS*/ 74 | static vector convex_hull (vector p) { 75 | if (p.size() <= 2) return p; 76 | 77 | int n = p.size(), k = 0; 78 | vector H(2*n); 79 | 80 | sort(p.begin(), p.end()); 81 | 82 | for (int i = 0; i < n; i++) { 83 | while (k >= 2 and ((H[k-1]-H[k-2])^(p[i]-H[k-2])) <= 0.0) k--; 84 | H[k++] = p[i]; 85 | } 86 | 87 | for (int i = n-2, t = k+1; i >= 0; i--) { 88 | while (k >= t and ((H[k-1]-H[k-2])^(p[i]-H[k-2])) <= 0.0) k--; 89 | H[k++] = p[i]; 90 | } 91 | 92 | H.resize(k-1); 93 | 94 | return H; 95 | } 96 | }; 97 | 98 | int main (void) { 99 | ios_base::sync_with_stdio(false); 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /math/geometry/geometry.cpp: -------------------------------------------------------------------------------- 1 | /*** Sumario 2 | * Lei dos Cossenos, Lei dos Senos 3 | * gcd 4 | * norm 5 | * sig_mul 6 | **Point 7 | * operators 8 | * len 9 | * ddp, ddp2 10 | * relative_proj 11 | * norm 12 | * perp 13 | * distToSegment 14 | * proj 15 | * rotaciona 16 | * area 17 | * convex_hull 18 | * ang 19 | * inter 20 | * intersect 21 | * inside 22 | * minRetangulo 23 | * max_dist 24 | * min_dist 25 | * max_ab 26 | * pick_theorem 27 | **Circle 28 | * intersect 29 | * circumcicle 30 | * cover 31 | * getAreaTriangle 32 | * */ 33 | #include 34 | 35 | using namespace std; 36 | 37 | #define mk make_pair 38 | #define pb push_back 39 | #define fi first 40 | #define se second 41 | 42 | typedef pair ii; 43 | typedef long long ll; 44 | const double EPS = 1e-9; 45 | const double PI = acos(-1.0); 46 | 47 | /* 48 | * /| 49 | * /A| 50 | * c/ |b 51 | * / | 52 | * /B__C| 53 | * a 54 | * Lei dos Cossenos: a**2 = b**2 + c**2 - 2*b*c*cos(A) 55 | * Lei dos Senos: a/sin(A) = b/sin(B) = c/sin(C) 56 | * 57 | * */ 58 | 59 | ll gcd (ll a, ll b) { 60 | if (!b) 61 | return a; 62 | else 63 | return gcd(b, a%b); 64 | } 65 | 66 | double norm(double x) { 67 | if(x > 0) return 1; 68 | if(x < 0) return -1; 69 | return 0; 70 | } 71 | 72 | double sig_mul(double a, double b) { 73 | a = norm(a); 74 | b = norm(b); 75 | return a*b; 76 | } 77 | 78 | class Point { 79 | public: 80 | double x, y; 81 | 82 | Point () { } 83 | 84 | Point (double x, double y) { 85 | this->x = x; 86 | this->y = y; 87 | } 88 | 89 | /**/ 90 | bool operator == (const Point &b) const { 91 | return (abs (x - b.x) < EPS and abs (y - b.y) < EPS); 92 | } 93 | 94 | /**/ 95 | bool operator < (const Point &b) const { 96 | return ((x < b.x) or ((x == b.x) and y < b.y)); 97 | } 98 | 99 | //Produto vetorial 100 | // p^q = |p|*|q|*sin(ang) ang: directed ang from p to q(-PI < ang <= PI) 101 | // p^q = 0 => ang = 0 or PI, p and q are colinear 102 | // p^q > 0 => 0 < ang < PI / p^q < 0 => -PI < ang < 0 103 | // p^q = directed area of paralelogram formed by vectors p and q 104 | // dist point p to line ab = ||ab^p|| / ||ab|| 105 | double operator ^ (const Point &b) const { 106 | return (this->x * b.y) - (this->y * b.x); 107 | } 108 | 109 | //Produto escalar 110 | // p*q = |p|*|q|*cos(ang) ang: inner ang (0 <= ang < PI) 111 | // p*q = 0 => ang = 90 / p*q > 0 => ang < 90 / p*q < 0 => ang > 90 112 | // p*p = |p|^2 => |p| = sqrt(p*p) 113 | double operator * (const Point &b) const { 114 | return (this->x * b.x) + (this->y * b.y); 115 | } 116 | 117 | /**/ 118 | Point operator * (double k) const { 119 | return Point (x*k, y*k); 120 | } 121 | 122 | Point operator / (double k) const { 123 | if (k == 0.0) cout << "Class Point (operador /): divisao por zero" << endl; 124 | return Point (x/k, y/k); 125 | } 126 | 127 | /**/ 128 | Point operator + (const Point &b) const { 129 | return Point (x + b.x, y + b.y); 130 | } 131 | 132 | /**/ 133 | Point operator - (const Point &b) const { 134 | return Point (x - b.x, y - b.y); 135 | } 136 | 137 | /**/ 138 | double len () const { 139 | return sqrt (x*x + y*y); 140 | } 141 | 142 | double dpp2 (const Point &b) const { 143 | return ((*this)-b)*((*this)-b); 144 | } 145 | 146 | /*Distancia ponto a ponto*/ 147 | double dpp (const Point &b) const { 148 | return ((*this)-b).len(); 149 | } 150 | 151 | /*Oriented relative length of projection of this over b*/ 152 | double relative_proj (Point &b) const { 153 | return ((*this)*b)/(b.len()*b.len()); 154 | } 155 | 156 | Point norm () const { 157 | return Point (x/this->len(), y/this->len()); 158 | } 159 | 160 | /*Retorna o vetor perpendicular ao vetor (0,0) -> (Point) 161 | Sentido clockwise*/ 162 | Point perp () const { 163 | return Point (this->y, -1.0 * this->x); 164 | } 165 | 166 | // Distancia do ponto p ao segmento ab, tambem retorna por 167 | // referencia o ponto (c) do segmento mais perto de p 168 | double distToSegment (const Point a, const Point b, Point &c) const { 169 | // formula: c = a + u * ab 170 | Point p = *this; 171 | if (a == b) return p.dpp(a); 172 | Point ap = Point(p - a), ab = Point(b - a); 173 | double u = ap.relative_proj(ab); 174 | if (u < 0.0) u = 0.0; 175 | if (u > 1.0) u = 1.0; 176 | c = a + ab * u; 177 | return p.dpp(c); 178 | } 179 | 180 | // Projection of this over v 181 | Point proj (const Point &v) const { 182 | return v*((*this)*v); 183 | } 184 | 185 | /**/ 186 | Point rotaciona (double ang) const { 187 | double c = cos(ang), s = sin(ang); 188 | double X = x*c - y*s; 189 | double Y = x*s + y*c; 190 | return Point(X,Y); 191 | } 192 | 193 | /*area de um poligono concavo ou convexo 194 | dado vetor de vertices ordenados clockwise ou 195 | counter clockwise*/ 196 | static double area (vector v) { 197 | double area = 0.0; 198 | for (int i = 0; i < (int)v.size(); i++) 199 | area += v[i] ^ v[(i+1)%v.size()]; 200 | return abs(area/2.0); 201 | } 202 | 203 | /* return counter clock points of convex hull 204 | * WITHOUT COLINEAR POINTS*/ 205 | static vector convex_hull (vector p) { 206 | if (p.size() <= 2) return p; 207 | 208 | int n = p.size(), k = 0; 209 | vector H(2*n); 210 | 211 | sort(p.begin(), p.end()); 212 | 213 | // Lower Hull 214 | for (int i = 0; i < n; i++) { 215 | while (k >= 2 and ((H[k-1]-H[k-2])^(p[i]-H[k-2])) <= 0.0) k--; 216 | H[k++] = p[i]; 217 | } 218 | 219 | // Upper Hull 220 | for (int i = n-2, t = k+1; i >= 0; i--) { 221 | while (k >= t and ((H[k-1]-H[k-2])^(p[i]-H[k-2])) <= 0.0) k--; 222 | H[k++] = p[i]; 223 | } 224 | 225 | H.resize(k-1); 226 | 227 | return H; 228 | } 229 | 230 | /*Angulo em forma de fracao reduzida entre o vetor Op (p é o ponto) 231 | e o eixo x, se paralelo ao eixo x retorna (1,0) ou (-1,0) 232 | se paralelo ao eixo y retorna (0,1) ou (0,-1) 233 | SÓ FUNCIONA PARA PONTOS INTEIROS*/ 234 | static ii ang (Point p) { 235 | ll a = p.x, b = p.y; 236 | if (a == 0) return mk(0, b/abs(b)); 237 | else if (b == 0) return mk(a/abs(a), 0); 238 | return mk(a/gcd(a,b), b/gcd(a,b)); 239 | } 240 | 241 | // Check if segment ab intersects with cd, considera endpoints como dentro 242 | static bool inter (const Point &a, const Point &b, const Point &c, const Point &d) { 243 | Point ab = b-a; 244 | Point ac = c-a; 245 | Point ad = d-a; 246 | 247 | Point cd = d-c; 248 | Point ca = a-c; 249 | Point cb = b-c; 250 | 251 | // a, b, c, d -> Colineares 252 | // Se estiver desconsiderando endpoints nao precisa, essa parte +- testada 253 | if(abs(ab^ac) < EPS and abs(ab^ad) < EPS) { 254 | Point bc = c-b; 255 | Point bd = d-b; 256 | Point da = a-d; 257 | Point db = b-d; 258 | if((ac*ad) <= 0.0) // < para descosiderar endpoints(soh igual a zero quando c=d) 259 | return true; 260 | if((bc*bd) <= 0.0) // < para descosiderar endpoints(soh igual a zero quando c=d) 261 | return true; 262 | if((ca*cb) <= 0.0) // < para descosiderar endpoints(soh igual a zero quando c=d) 263 | return true; 264 | if((da*db) <= 0.0) // < para descosiderar endpoints(soh igual a zero quando c=d) 265 | return true; 266 | return false; 267 | } 268 | 269 | // >= para desconsiderar endpoints 270 | if(sig_mul(ab^ac, ab^ad) > 0.0) 271 | return false; 272 | 273 | // >= para desconsiderar endpoints 274 | if(sig_mul(cd^ca, cd^cb) > 0.0) 275 | return false; 276 | 277 | return true; 278 | } 279 | 280 | /*Interseccao de dois vetores somandos a pontos, returns t that p1 + v1*t = P_inter*/ 281 | static double intersect (Point p1, Point v1, Point p2, Point v2) { 282 | if (abs(v2 ^ v1) >= EPS) { 283 | Point c = p1 - p2; 284 | return (c ^ v2)/(v2 ^v1); 285 | } else { 286 | cout << "Class Point (funcao inter): retas paralelas" << endl; 287 | cout << "Talvez deva ajustar o EPS" << endl; 288 | } 289 | return 0.0; 290 | } 291 | 292 | /* Retorna se point p esta dentro do poligono convexo v, pontos de v estao 293 | * em counter clockwise 294 | * Considera borda como fora 295 | * O(log2(v.size()))*/ 296 | static bool inside(const vector &v, const Point &p) { 297 | // V DEVE ESTAR EM COUNTER CLOCKWISE 298 | int n = v.size(); 299 | 300 | if(n < 3) 301 | return false; 302 | 303 | // Considerar borda como dentro: mudar para < 304 | if(((v[1]-v[0])^(p-v[0])) <= 0) 305 | return false; 306 | 307 | int bot = 2, top = n-1; 308 | int ans = -1; 309 | while(bot <= top) { 310 | int mid = (bot+top)>>1; 311 | 312 | // Considerar borda como dentro: mudar para <= 313 | if(((v[mid]-v[0])^(p-v[0])) < 0) { 314 | ans = mid; 315 | top = mid-1; 316 | } else { 317 | bot = mid+1; 318 | } 319 | } 320 | 321 | if(ans == -1) 322 | return false; 323 | 324 | // Considerar borda como dentro: mudar para < 325 | if(((v[ans]-v[ans-1])^(p-v[ans-1])) <= 0) 326 | return false; 327 | 328 | return true; 329 | } 330 | 331 | /*Retorna o retangulo (pontos em anti clockwise) que tem a menor valor 332 | min(Xmax -Xmin, Ymax - Ymin)*/ 333 | static vector minRetangulo (vector v) { 334 | vector at; 335 | at.pb(Point(-1e18, -1e18)); 336 | at.pb(Point(1e18, -1e18)); 337 | at.pb(Point(1e18, 1e18)); 338 | at.pb(Point(-1e18, 1e18)); 339 | v = convex_hull(v); 340 | int n = v.size(); 341 | for (int i = 0; i < n; i++) { 342 | int j = (i+1)%n; 343 | Point vec = v[j] - v[i]; 344 | double ang = atan2(vec.y, vec.x); 345 | vector ve; 346 | for (int j = 0; j < n; j++) { 347 | ve.pb(v[j].rotaciona(ang)); 348 | } 349 | double minx = DBL_MAX, miny = DBL_MAX, maxx = -DBL_MAX, maxy = -DBL_MAX; 350 | for (int j = 0; j < n; j++) { 351 | if (ve[j].x < minx) minx = ve[j].x; 352 | if (ve[j].x > maxx) maxx = ve[j].x; 353 | if (ve[j].y < miny) miny = ve[j].y; 354 | if (ve[j].y > maxy) maxy = ve[j].y; 355 | } 356 | double mini = min(maxx - minx, maxy - miny); 357 | if (mini < min(at[2].x - at[0].x, at[2].y - at[0].y)) { 358 | at.clear(); 359 | at.pb(Point(minx, miny)); 360 | at.pb(Point(maxx, miny)); 361 | at.pb(Point(maxx, maxy)); 362 | at.pb(Point(minx, maxy)); 363 | } 364 | } 365 | 366 | return at; 367 | } 368 | 369 | // distance of 2 farthest points. O(n) + O(convex_hull) 370 | // Rotating Calipers 371 | static double max_dist (vector p) { 372 | double ret = 0; 373 | p = Point::convex_hull(p); 374 | 375 | int n = p.size(); 376 | if (n <= 1) 377 | return 0; 378 | if (n == 2) 379 | return p[0].dpp(p[1]); 380 | 381 | int at = 1; 382 | for (int i = 0; i < n; i++) { 383 | int j = (i + 1)%n; 384 | 385 | Point v = p[j] - p[i]; 386 | int nxt = (at + 1)%n; 387 | while (nxt != i and (v^(p[nxt]-p[i])) >= (v^(p[at]-p[i]))) { 388 | at = nxt; 389 | nxt = (at + 1)%n; 390 | } 391 | 392 | ret = max (ret, max (p[i].dpp(p[at]), p[j].dpp(p[at]))); 393 | } 394 | 395 | return ret; 396 | } 397 | 398 | // ** MIN DIST BEGIN O(N*LOG2(N)) N = number of points 399 | static bool compy (const Point &a, const Point &b) { 400 | if (a.y != b.y) return a.y < b.y; 401 | return a.x < b.x; 402 | } 403 | 404 | static void min_dist (const Point &p, const vector &v, int i, double &d) { 405 | while (i < (int)v.size() and v[i].y - p.y < d) { 406 | d = min (d, p.dpp(v[i])); 407 | i++; 408 | } 409 | } 410 | 411 | // divide and conquer 412 | static vector min_dist (const vector &p, int l, int r, double &d) { 413 | vector ret; 414 | if (l == r) { 415 | ret.pb(p[l]); 416 | return ret; 417 | } 418 | int mid = (l + r)>>1; 419 | 420 | vector L = min_dist (p, l, mid, d); 421 | vector R = min_dist (p, mid + 1, r, d); 422 | 423 | vector vl, vr; 424 | for (auto it : L) 425 | if (p[mid].x - it.x < d) 426 | vl.pb(it); 427 | 428 | for (auto it : R) 429 | if (it.x - p[mid + 1].x < d) 430 | vr.pb(it); 431 | 432 | int i = 0, j = 0; 433 | 434 | while (i < (int)vl.size() and j < (int)vr.size()) { 435 | if (vl[i].y < vr[j].y) { 436 | min_dist (vl[i], vr, j, d); 437 | i++; 438 | } else { 439 | min_dist (vr[j], vl, i, d); 440 | j++; 441 | } 442 | } 443 | 444 | ret.resize(r - l + 1); 445 | merge (L.begin(), L.end(), R.begin(), R.end(), 446 | ret.begin(), compy); 447 | return ret; 448 | } 449 | 450 | // PUBLIC 451 | static double min_dist (vector p) { 452 | if (p.size() <= 1) return 0.0; 453 | sort (p.begin(), p.end()); 454 | 455 | double dist = p[0].dpp(p[1]); 456 | min_dist (p, 0, p.size() - 1, dist); 457 | return dist; 458 | } 459 | // ** MIN DIST END 460 | 461 | // ** MAX A*X + B*Y BEGIN 462 | // ternary search 463 | static double max_ab (const vector &p, int bot, int top, const Point &ab) { 464 | if (bot > top) return -1e18; 465 | double ret = max (ab*p[bot], ab*p[top]); 466 | top--; 467 | 468 | while (bot <= top) { 469 | int mid = (bot + top)>>1; 470 | 471 | ret = max (ret, max(p[mid]*ab, p[mid+1]*ab)); 472 | 473 | if (p[mid]*ab > p[mid+1]*ab) { 474 | top = mid - 1; 475 | } else { 476 | bot = mid + 1; 477 | } 478 | } 479 | 480 | return ret; 481 | } 482 | 483 | static double max_ab (const vector &p, const Point &ab) { 484 | int n = p.size(); 485 | 486 | if (n < 10) { 487 | double ret = ab*p[0]; 488 | for (int i = 1; i <= n; i++) 489 | ret = max(ret, ab*p[i]); 490 | return ret; 491 | } 492 | 493 | Point perp = ab.perp(); 494 | 495 | int split = 0; 496 | int bot = 0, top = n - 1; 497 | 498 | double dir = perp^(p[1]-p[0]); 499 | if (!dir) { 500 | bot = 1; 501 | dir = perp^(p[2]-p[0]); 502 | } 503 | 504 | if (dir > 0) 505 | dir = 1; 506 | else 507 | dir = -1; 508 | 509 | // normal divides the convex hull, to get 2 ranges where ternary search is possible 510 | while (bot <= top) { 511 | int mid = (bot + top)>>1; 512 | 513 | if ((perp^(p[mid]-p[0])) * dir > 0) { 514 | bot = mid + 1; 515 | split = mid; 516 | } else { 517 | top = mid - 1; 518 | } 519 | } 520 | 521 | return max (max_ab(p, 0, split, ab), max_ab(p, split + 1, n, ab)); 522 | } 523 | 524 | // PUBLIC 525 | // O(convex_hull(p)) + ab.size()*log2(p.size()) 526 | static vector max_ab (vector p, const vector &ab) { 527 | // convex_hull WITHOUT COLINEAR POINTS 528 | p = Point::convex_hull(p); 529 | vector ans(ab.size()); 530 | 531 | int n = ab.size(); 532 | for (int i = 0; i < n; i++) 533 | ans[i] = max_ab(p, ab[i]); 534 | 535 | return ans; 536 | } 537 | // ** MAX A*X + B*Y END 538 | 539 | /* 540 | Teorema de Pick: 541 | Um polígono construído sobre uma grade de pontos equidistantes. 542 | Dado um polígono simples construído sobre uma grade de pontos equidistantes (i.e., pontos com coordenadas inteiras) 543 | de tal forma que todos os vértices do polígono sejam pontos da grade, o teorema de Pick fornece uma fórmula simples 544 | para o cálculo da área A desse polígono em termos do número i de pontos interiores localizados no polígono, 545 | e o número b de pontos fronteiriços localizados no perímetro do polígono: 546 | A = i + b/2 - 1 547 | 548 | i = A - b/2 + 1 549 | Os pontos devem ser inteiros 550 | */ 551 | static ll pick_theorem(const vector &p) { 552 | int n = p.size(); 553 | ll A = 0, b = 0; 554 | 555 | for(int i = 0; i < n; i++) { 556 | int j = (i+1)%n; 557 | A += p[i]^p[j]; 558 | 559 | ll xx = abs(p[j].x - p[i].x); 560 | ll yy = abs(p[j].y - p[i].y); 561 | 562 | b += gcd(xx, yy); 563 | } 564 | 565 | if(A < 0) A *= -1; 566 | A>>=1; 567 | 568 | ll ans = A - (b>>1) + 1; 569 | return ans; 570 | } 571 | }; 572 | 573 | ostream &operator<<(ostream &os, Point const &p) { 574 | return os << p.x << " " << p.y; 575 | } 576 | 577 | class Circle { 578 | public: 579 | Point c; 580 | double r; 581 | 582 | Circle () {} 583 | 584 | Circle (const Point &c, double r) : c(c), r(r) {} 585 | 586 | /*Interseccao de dois circulos 587 | OBS: se ha infinitas interseccoes retorna o vetor vazio 588 | OBS: se existe só um ponto retorna 2 pontos iguais*/ 589 | vector intersect (Circle b) { 590 | vector ret; 591 | Point c1 = this->c, c2 = b.c; 592 | double r1 = this->r, r2 = b.r; 593 | 594 | if (c1 == c2) return ret; 595 | 596 | double d = c1.dpp(c2); 597 | 598 | if (d > r1 + r2 + EPS) return ret; 599 | if (d + EPS < abs(r1 - r2)) return ret; 600 | 601 | double a = (r1*r1 - r2*r2 + d*d)/(2.0*d); 602 | double h = sqrt(max(0.0, r1*r1 - a*a)); 603 | 604 | Point pc = c1 + ((c2 - c1)*a)/d; 605 | 606 | /*X EH MENOS E Y EH MAIS*/ 607 | double x = pc.x - ((h*(c2.y - c1.y))/d); 608 | double y = pc.y + ((h*(c2.x - c1.x))/d); 609 | ret.pb(Point(x,y)); 610 | 611 | x = pc.x + ((h*(c2.y - c1.y))/d); 612 | y = pc.y - ((h*(c2.x - c1.x))/d); 613 | ret.pb(Point(x,y)); 614 | 615 | return ret; 616 | } 617 | 618 | // Circumcircle of a triangle, TAKE CARE WITH 3 COLINEAR POINTS 619 | static Circle circumcircle (const Point &a, const Point &b, const Point &c) { 620 | Point ab = b - a, bc = c - b; 621 | Point mab = a + ab * 0.5; 622 | Point mbc = b + bc * 0.5; 623 | 624 | double a1 = ab.x, b1 = ab.y; 625 | double c1 = -a1 * mab.x - b1 * mab.y; 626 | 627 | double a2 = bc.x, b2 = bc.y; 628 | double c2 = -a2 * mbc.x - b2 * mbc.y; 629 | 630 | double den = a1 * b2 - a2 * b1; 631 | 632 | double x = (-c1 * b2 + b1 * c2)/den; 633 | double y = (-c2 * a1 + a2 * c1)/den; 634 | 635 | Point center(x, y); 636 | return Circle(center, (a-center).len()); 637 | } 638 | 639 | // Randomize O(p.size()) 640 | // Return circle that covers all point in p with minimum radius 641 | // Idea: if some point pt is outside of current circle, make new circle with previous points 642 | // in circle, this circle will have point pt on the border 643 | // With 3 points on the border its easy to get the circle (Circumcicle) 644 | static Circle cover (vector p, vector border = vector ()) { 645 | random_shuffle(p.begin(), p.end()); 646 | 647 | Circle res; 648 | if (border.size() == 0) 649 | res = Circle(p[0], 0.0); 650 | else if (border.size() == 1) 651 | res = Circle(border[0], 0.0); 652 | else if (border.size() == 2) 653 | res = Circle((border[0] + border[1])*0.5, (border[0].dpp(border[1]))/2.0); 654 | else 655 | return circumcircle (border[0], border[1], border[2]); 656 | 657 | vector p2; 658 | for (auto pt : p) { 659 | if (res.c.dpp(pt) > res.r) { 660 | border.pb(pt); 661 | res = cover (p2, border); 662 | border.pop_back(); 663 | } 664 | p2.pb(pt); 665 | } 666 | 667 | return res; 668 | } 669 | 670 | // Retorna os pontos da tangente externa entre os circulo a e b 671 | // Soh funciona se a e b nao estao contidos inteiramente um no outro 672 | static vector outter_tang(Circle a, Circle b) { 673 | vector ret; 674 | // a eh o circulo de maior area 675 | if(a.r < b.r) 676 | swap(a, b); 677 | // raio iguais n tem ponto de interseccao das duas tangentes 678 | // os vetor do raio ao ponto da tangente eh perpenditular ao vetor que liga os centros 679 | if(abs(a.r-b.r) < EPS) { 680 | double dist = a.c.dpp(b.c); 681 | Point vv = a.c-b.c; 682 | vv = Point(vv.y, -vv.x); 683 | 684 | double len_ratio = a.r / dist; 685 | ret.pb(a.c + vv*len_ratio); 686 | ret.pb(a.c - vv*len_ratio); 687 | 688 | len_ratio = b.r / dist; 689 | ret.pb(b.c + vv*len_ratio); 690 | ret.pb(b.c - vv*len_ratio); 691 | 692 | return ret; 693 | } 694 | return ret; 695 | 696 | double dist = a.c.dpp(b.c); 697 | // distancia entre a.c e o ponto de interseccao das tangentes 698 | double h = (dist * a.r) / (a.r - b.r); 699 | 700 | // ponto de interseccao das tangentes 701 | Point p = a.c + ((b.c - a.c) * (h / dist)); 702 | 703 | double len_ratio = sqrt(h*h - a.r*a.r) / h; 704 | ret.pb( p + (a.c-p).rotaciona(asin(a.r/h))*len_ratio); 705 | ret.pb( p + (a.c-p).rotaciona(-asin(a.r/h))*len_ratio ); 706 | 707 | len_ratio = sqrt((h-dist)*(h-dist) - b.r*b.r) / (h-dist); 708 | ret.pb( p + (b.c-p).rotaciona(asin(b.r/(h-dist)))*len_ratio ); 709 | ret.pb( p + (b.c-p).rotaciona(-asin(b.r/(h-dist)))*len_ratio ); 710 | 711 | return ret; 712 | } 713 | }; 714 | 715 | /* Get area of a nondegenerate triangle, with sides a, b, c */ 716 | double getAreaTriangle (double a, double b, double c) { 717 | double p = (a + b + c)/2.0; 718 | return sqrt (p * (p - a) * (p - b) * (p - c)); 719 | } 720 | 721 | int main (void) { 722 | ios_base::sync_with_stdio(false); 723 | 724 | return 0; 725 | } 726 | -------------------------------------------------------------------------------- /math/geometry/geometryT.cpp: -------------------------------------------------------------------------------- 1 | /* Behind geometry.cpp */ 2 | #include 3 | 4 | using namespace std; 5 | 6 | #define mk make_pair 7 | #define pb push_back 8 | #define fi first 9 | #define se second 10 | 11 | typedef pair ii; 12 | typedef long long ll; 13 | const double EPS = 1e-9; 14 | const double PI = acos(-1.0); 15 | 16 | ll gcd (ll a, ll b) { 17 | if (!b) 18 | return a; 19 | else 20 | return gcd(b, a%b); 21 | } 22 | 23 | template 24 | class Point { 25 | public: 26 | T x, y; 27 | 28 | Point () { } 29 | 30 | Point (T x, T y) : x(x), y(y) {} 31 | 32 | /**/ 33 | bool operator == (const Point &b) const { 34 | return (abs (x - b.x) < EPS and abs (y - b.y) < EPS); 35 | } 36 | 37 | /**/ 38 | bool operator < (const Point &b) const { 39 | return ((x < b.x) or ((x == b.x) and y < b.y)); 40 | } 41 | 42 | //Produto vetorial 43 | // p^q = |p|*|q|*sin(ang) ang: directed ang from p to q(-PI < ang <= PI) 44 | // p^q = 0 => ang = 0 or PI, p and q are colinear 45 | // p^q > 0 => 0 < ang < PI / p^q < 0 => -PI < ang < 0 46 | // p^q = directed area of paralelogram formed by vectors p and q 47 | // dist point p to line ab = ||ab^p|| / ||ab|| 48 | T operator ^ (const Point &b) const { 49 | return (this->x * b.y) - (this->y * b.x); 50 | } 51 | 52 | //Produto escalar 53 | // p*q = |p|*|q|*cos(ang) ang: inner ang (0 <= ang < PI) 54 | // p*q = 0 => ang = 90 / p*q > 0 => ang < 90 / p*q < 0 => ang > 90 55 | // p*p = |p|^2 => |p| = sqrt(p*p) 56 | T operator * (const Point &b) const { 57 | return (this->x * b.x) + (this->y * b.y); 58 | } 59 | 60 | /**/ 61 | Point operator * (T k) const { 62 | return Point (x*k, y*k); 63 | } 64 | 65 | Point operator / (T k) const { 66 | if (k == 0) cout << "Class Point (operador /): divisao por zero" << endl; 67 | return Point (x/k, y/k); 68 | } 69 | 70 | /**/ 71 | Point operator + (const Point &b) const { 72 | return Point (x + b.x, y + b.y); 73 | } 74 | 75 | /**/ 76 | Point operator - (const Point &b) const { 77 | return Point (x - b.x, y - b.y); 78 | } 79 | 80 | /**/ 81 | T len2 () const { 82 | return x*x + y*y; 83 | } 84 | 85 | /**/ 86 | T len () const { 87 | return sqrt (x*x + y*y); 88 | } 89 | 90 | /**/ 91 | T dpp2 (const Point &b) const { 92 | return ((*this)-b)*((*this)-b); 93 | } 94 | 95 | /*Distancia ponto a ponto*/ 96 | T dpp (const Point &b) const { 97 | return ((*this)-b).len(); 98 | } 99 | 100 | /*Oriented relative length of projection of this over b*/ 101 | T relative_proj (Point &b) const { 102 | return ((*this)*b)/(b.len()*b.len()); 103 | } 104 | 105 | Point norm () const { 106 | return Point (x/this->len(), y/this->len()); 107 | } 108 | 109 | /*Retorna o vetor perpendicular ao vetor (0,0) -> (Point) 110 | Sentido clockwise*/ 111 | Point perp () const { 112 | return Point (this->y, -1.0 * this->x); 113 | } 114 | 115 | // Distancia do ponto p ao segmento ab, tambem retorna por 116 | // referencia o ponto (c) do segmento mais perto de p 117 | T distToSegment (const Point a, const Point b, Point &c) const { 118 | // formula: c = a + u * ab 119 | Point p = *this; 120 | if (a == b) return p.dpp(a); 121 | Point ap = Point(p - a), ab = Point(b - a); 122 | T u = ap.relative_proj(ab); 123 | if (u < 0.0) u = 0.0; 124 | if (u > 1.0) u = 1.0; 125 | c = a + ab * u; 126 | return p.dpp(c); 127 | } 128 | 129 | // Projection of this over v 130 | Point proj (const Point &v) const { 131 | return v*((*this)*v); 132 | } 133 | 134 | /**/ 135 | Point rotaciona (T ang) const { 136 | T c = cos(ang), s = sin(ang); 137 | T X = x*c - y*s; 138 | T Y = x*s + y*c; 139 | return Point(X,Y); 140 | } 141 | 142 | /*area de um poligono concavo ou convexo 143 | dado vetor de vertices ordenados clockwise ou 144 | counter clockwise*/ 145 | static T area (vector v) { 146 | T area = 0.0; 147 | for (int i = 0; i < (int)v.size(); i++) 148 | area += v[i] ^ v[(i+1)%v.size()]; 149 | return abs(area/2.0); 150 | } 151 | 152 | /* return counter clock points of convex hull 153 | * WITHOUT COLINEAR POINTS*/ 154 | static vector convex_hull (vector p) { 155 | if (p.size() <= 2) return p; 156 | 157 | int n = p.size(), k = 0; 158 | vector H(2*n); 159 | 160 | sort(p.begin(), p.end()); 161 | 162 | for (int i = 0; i < n; i++) { 163 | while (k >= 2 and ((H[k-1]-H[k-2])^(p[i]-H[k-2])) <= 0.0) k--; 164 | H[k++] = p[i]; 165 | } 166 | 167 | for (int i = n-2, t = k+1; i >= 0; i--) { 168 | while (k >= t and ((H[k-1]-H[k-2])^(p[i]-H[k-2])) <= 0.0) k--; 169 | H[k++] = p[i]; 170 | } 171 | 172 | H.resize(k-1); 173 | 174 | return H; 175 | } 176 | 177 | /*Angulo em forma de fracao reduzida entre o vetor Op (p é o ponto) 178 | e o eixo x, se paralelo ao eixo x retorna (1,0) ou (-1,0) 179 | se paralelo ao eixo y retorna (0,1) ou (0,-1) 180 | SÓ FUNCIONA PARA PONTOS INTEIROS*/ 181 | static ii ang (Point p) { 182 | ll a = p.x, b = p.y; 183 | if (a == 0) return mk(0, b/abs(b)); 184 | else if (b == 0) return mk(a/abs(a), 0); 185 | return mk(a/gcd(a,b), b/gcd(a,b)); 186 | } 187 | 188 | /*Interseccao de dois vetores somandos a pontos*/ 189 | static T inter (Point p1, Point v1, Point p2, Point v2) { 190 | if (abs(v2 ^ v1) >= EPS) { 191 | Point c = p1 - p2; 192 | return (c ^ v2)/(v2 ^v1); 193 | } else { 194 | cout << "Class Point (funcao inter): retas paralelas" << endl; 195 | cout << "Talvez deva ajustar o EPS" << endl; 196 | } 197 | return 0.0; 198 | } 199 | 200 | /* Retorna se point p esta dentro do poligono convexo v, pontos de v estao 201 | * em counter clockwise 202 | * Considera borda como fora 203 | * O(log2(v.size()))*/ 204 | static bool inside(const vector &v, const Point &p) { 205 | // V DEVE ESTAR EM COUNTER CLOCKWISE 206 | int n = v.size(); 207 | 208 | if(n < 3) 209 | return false; 210 | 211 | // Considerar borda como dentro: mudar para < 212 | if(((v[1]-v[0])^(p-v[0])) <= 0) 213 | return false; 214 | 215 | int bot = 2, top = n-1; 216 | int ans = -1; 217 | while(bot <= top) { 218 | int mid = (bot+top)>>1; 219 | 220 | // Considerar borda como dentro: mudar para <= 221 | if(((v[mid]-v[0])^(p-v[0])) < 0) { 222 | ans = mid; 223 | top = mid-1; 224 | } else { 225 | bot = mid+1; 226 | } 227 | } 228 | 229 | if(ans == -1) 230 | return false; 231 | 232 | // Considerar borda como dentro: mudar para < 233 | if(((v[ans]-v[ans-1])^(p-v[ans-1])) <= 0) 234 | return false; 235 | 236 | return true; 237 | } 238 | 239 | /*Retorna o retangulo (pontos em anti clockwise) que tem a menor valor 240 | min(Xmax -Xmin, Ymax - Ymin)*/ 241 | static vector minRetangulo (vector v) { 242 | vector at; 243 | at.pb(Point(-1e18, -1e18)); 244 | at.pb(Point(1e18, -1e18)); 245 | at.pb(Point(1e18, 1e18)); 246 | at.pb(Point(-1e18, 1e18)); 247 | v = convex_hull(v); 248 | int n = v.size(); 249 | for (int i = 0; i < n; i++) { 250 | int j = (i+1)%n; 251 | Point vec = v[j] - v[i]; 252 | T ang = atan2(vec.y, vec.x); 253 | vector ve; 254 | for (int j = 0; j < n; j++) { 255 | ve.pb(v[j].rotaciona(ang)); 256 | } 257 | T minx, miny, maxx, maxy; 258 | 259 | minx = miny = numeric_limits::max(); 260 | maxx = maxy = numeric_limits::min(); 261 | 262 | for (int j = 0; j < n; j++) { 263 | if (ve[j].x < minx) minx = ve[j].x; 264 | if (ve[j].x > maxx) maxx = ve[j].x; 265 | if (ve[j].y < miny) miny = ve[j].y; 266 | if (ve[j].y > maxy) maxy = ve[j].y; 267 | } 268 | T mini = min(maxx - minx, maxy - miny); 269 | if (mini < min(at[2].x - at[0].x, at[2].y - at[0].y)) { 270 | at.clear(); 271 | at.pb(Point(minx, miny)); 272 | at.pb(Point(maxx, miny)); 273 | at.pb(Point(maxx, maxy)); 274 | at.pb(Point(minx, maxy)); 275 | } 276 | } 277 | 278 | return at; 279 | } 280 | 281 | // distance of 2 farthest points. O(n) + O(convex_hull) 282 | // Rotating Calipers 283 | static T max_dist (vector p) { 284 | T ret = 0; 285 | p = Point::convex_hull(p); 286 | 287 | int n = p.size(); 288 | if (n <= 1) 289 | return 0; 290 | if (n == 2) 291 | return p[0].dpp(p[1]); 292 | 293 | int at = 1; 294 | for (int i = 0; i < n; i++) { 295 | int j = (i + 1)%n; 296 | 297 | Point v = p[j] - p[i]; 298 | int nxt = (at + 1)%n; 299 | while (nxt != i and (v^(p[nxt]-p[i])) >= (v^(p[at]-p[i]))) { 300 | at = nxt; 301 | nxt = (at + 1)%n; 302 | } 303 | 304 | ret = max (ret, max (p[i].dpp(p[at]), p[j].dpp(p[at]))); 305 | } 306 | 307 | return ret; 308 | } 309 | 310 | // ** MIN DIST BEGIN O(N*LOG2(N)) N = number of points 311 | static bool compy (const Point &a, const Point &b) { 312 | if (a.y != b.y) return a.y < b.y; 313 | return a.x < b.x; 314 | } 315 | 316 | static void min_dist (const Point &p, const vector &v, int i, T &d) { 317 | while (i < (int)v.size() and v[i].y - p.y < d) { 318 | d = min (d, p.dpp(v[i])); 319 | i++; 320 | } 321 | } 322 | 323 | // divide and conquer 324 | static vector min_dist (const vector &p, int l, int r, T &d) { 325 | vector ret; 326 | if (l == r) { 327 | ret.pb(p[l]); 328 | return ret; 329 | } 330 | int mid = (l + r)>>1; 331 | 332 | vector L = min_dist (p, l, mid, d); 333 | vector R = min_dist (p, mid + 1, r, d); 334 | 335 | vector vl, vr; 336 | for (auto it : L) 337 | if (p[mid].x - it.x < d) 338 | vl.pb(it); 339 | 340 | for (auto it : R) 341 | if (it.x - p[mid + 1].x < d) 342 | vr.pb(it); 343 | 344 | int i = 0, j = 0; 345 | 346 | while (i < (int)vl.size() and j < (int)vr.size()) { 347 | if (vl[i].y < vr[j].y) { 348 | min_dist (vl[i], vr, j, d); 349 | i++; 350 | } else { 351 | min_dist (vr[j], vl, i, d); 352 | j++; 353 | } 354 | } 355 | 356 | ret.resize(r - l + 1); 357 | merge (L.begin(), L.end(), R.begin(), R.end(), 358 | ret.begin(), compy); 359 | return ret; 360 | } 361 | 362 | // PUBLIC 363 | static T min_dist (vector p) { 364 | if (p.size() <= 1) return 0.0; 365 | sort (p.begin(), p.end()); 366 | 367 | T dist = p[0].dpp(p[1]); 368 | min_dist (p, 0, p.size() - 1, dist); 369 | return dist; 370 | } 371 | // ** MIN DIST END 372 | 373 | // ** MAX A*X + B*Y BEGIN 374 | // ternary search 375 | static T max_ab (const vector &p, int bot, int top, const Point &ab) { 376 | if (bot > top) return -1e18; 377 | T ret = max (ab*p[bot], ab*p[top]); 378 | top--; 379 | 380 | while (bot <= top) { 381 | int mid = (bot + top)>>1; 382 | 383 | ret = max (ret, max(p[mid]*ab, p[mid+1]*ab)); 384 | 385 | if (p[mid]*ab > p[mid+1]*ab) { 386 | top = mid - 1; 387 | } else { 388 | bot = mid + 1; 389 | } 390 | } 391 | 392 | return ret; 393 | } 394 | 395 | static T max_ab (const vector &p, const Point &ab) { 396 | int n = p.size(); 397 | 398 | if (n < 10) { 399 | T ret = ab*p[0]; 400 | for (int i = 1; i <= n; i++) 401 | ret = max(ret, ab*p[i]); 402 | return ret; 403 | } 404 | 405 | Point perp = ab.perp(); 406 | 407 | int split = 0; 408 | int bot = 0, top = n - 1; 409 | 410 | T dir = perp^(p[1]-p[0]); 411 | if (!dir) { 412 | bot = 1; 413 | dir = perp^(p[2]-p[0]); 414 | } 415 | 416 | if (dir > 0) 417 | dir = 1; 418 | else 419 | dir = -1; 420 | 421 | // normal divides the convex hull, to get 2 ranges where ternary search is possible 422 | while (bot <= top) { 423 | int mid = (bot + top)>>1; 424 | 425 | if ((perp^(p[mid]-p[0])) * dir > 0) { 426 | bot = mid + 1; 427 | split = mid; 428 | } else { 429 | top = mid - 1; 430 | } 431 | } 432 | 433 | return max (max_ab(p, 0, split, ab), max_ab(p, split + 1, n, ab)); 434 | } 435 | 436 | // PUBLIC 437 | // O(convex_hull(p)) + ab.size()*log2(p.size()) 438 | static vector max_ab (vector p, const vector &ab) { 439 | // convex_hull WITHOUT COLINEAR POINTS 440 | p = Point::convex_hull(p); 441 | vector ans(ab.size()); 442 | 443 | int n = ab.size(); 444 | for (int i = 0; i < n; i++) 445 | ans[i] = max_ab(p, ab[i]); 446 | 447 | return ans; 448 | } 449 | // ** MAX A*X + B*Y END 450 | /* 451 | Teorema de Pick: 452 | Um polígono construído sobre uma grade de pontos equidistantes. 453 | Dado um polígono simples construído sobre uma grade de pontos equidistantes (i.e., pontos com coordenadas inteiras) 454 | de tal forma que todos os vértices do polígono sejam pontos da grade, o teorema de Pick fornece uma fórmula simples 455 | para o cálculo da área A desse polígono em termos do número i de pontos interiores localizados no polígono, 456 | e o número b de pontos fronteiriços localizados no perímetro do polígono: 457 | A = i + b/2 - 1 458 | 459 | i = A - b/2 + 1 460 | Os pontos devem ser inteiros 461 | */ 462 | static ll pick_theorem(const vector &p) { 463 | int n = p.size(); 464 | ll A = 0, b = 0; 465 | 466 | for(int i = 0; i < n; i++) { 467 | int j = (i+1)%n; 468 | A += p[i]^p[j]; 469 | 470 | ll xx = abs(p[j].x - p[i].x); 471 | ll yy = abs(p[j].y - p[i].y); 472 | 473 | b += gcd(xx, yy); 474 | } 475 | 476 | if(A < 0) A *= -1; 477 | A>>=1; 478 | 479 | ll ans = A - (b>>1) + 1; 480 | return ans; 481 | } 482 | }; 483 | 484 | template 485 | ostream &operator<<(ostream &os, Point const &p) { 486 | return os << p.x << " " << p.y; 487 | } 488 | 489 | template 490 | class Circle { 491 | public: 492 | Point c; 493 | T r; 494 | 495 | Circle () {} 496 | 497 | Circle (const Point &c, T r) : c(c), r(r) {} 498 | 499 | /*Interseccao de dois circulos 500 | OBS: se ha infinitas interseccoes retorna o vetor vazio 501 | OBS: se existe só um ponto retorna 2 pontos iguais*/ 502 | vector > intersect (Circle b) { 503 | vector > ret; 504 | Point c1 = this->c, c2 = b.c; 505 | T r1 = this->r, r2 = b.r; 506 | 507 | if (c1 == c2) return ret; 508 | 509 | T d = c1.dpp(c2); 510 | 511 | if (d > r1 + r2 + EPS) return ret; 512 | if (d + EPS < abs(r1 - r2)) return ret; 513 | 514 | T a = (r1*r1 - r2*r2 + d*d)/(2.0*d); 515 | T h = sqrt(max(0.0, r1*r1 - a*a)); 516 | 517 | Point pc = c1 + ((c2 - c1)*a)/d; 518 | 519 | /*X EH MENOS E Y EH MAIS*/ 520 | T x = pc.x - ((h*(c2.y - c1.y))/d); 521 | T y = pc.y + ((h*(c2.x - c1.x))/d); 522 | ret.pb(Point(x,y)); 523 | 524 | x = pc.x + ((h*(c2.y - c1.y))/d); 525 | y = pc.y - ((h*(c2.x - c1.x))/d); 526 | ret.pb(Point(x,y)); 527 | 528 | return ret; 529 | } 530 | 531 | // Circumcircle of a triangle, TAKE CARE WITH 3 COLINEAR POINTS 532 | static Circle circumcircle (const Point &a, const Point &b, const Point &c) { 533 | Point ab = b - a, bc = c - b; 534 | Point mab = a + ab * 0.5; 535 | Point mbc = b + bc * 0.5; 536 | 537 | T a1 = ab.x, b1 = ab.y; 538 | T c1 = -a1 * mab.x - b1 * mab.y; 539 | 540 | T a2 = bc.x, b2 = bc.y; 541 | T c2 = -a2 * mbc.x - b2 * mbc.y; 542 | 543 | T den = a1 * b2 - a2 * b1; 544 | 545 | T x = (-c1 * b2 + b1 * c2)/den; 546 | T y = (-c2 * a1 + a2 * c1)/den; 547 | 548 | Point center(x, y); 549 | return Circle(center, (a-center).len()); 550 | } 551 | 552 | // Randomize O(p.size()) 553 | // Return circle that covers all point in p with minimum radius 554 | // Idea: if some point pt is outside of current circle, make new circle with previous points 555 | // in circle, this circle will have point pt on the border 556 | // With 3 points on the border its easy to get the circle (Circumcicle) 557 | static Circle cover (vector > p, vector > border = vector >()) { 558 | random_shuffle(p.begin(), p.end()); 559 | 560 | Circle res; 561 | if (border.size() == 0) 562 | res = Circle(p[0], 0.0); 563 | else if (border.size() == 1) 564 | res = Circle(border[0], 0.0); 565 | else if (border.size() == 2) 566 | res = Circle((border[0] + border[1])*0.5, (border[0].dpp(border[1]))/2.0); 567 | else 568 | return circumcircle (border[0], border[1], border[2]); 569 | 570 | vector > p2; 571 | for (auto pt : p) { 572 | if (res.c.dpp(pt) > res.r) { 573 | border.pb(pt); 574 | res = cover (p2, border); 575 | border.pop_back(); 576 | } 577 | p2.pb(pt); 578 | } 579 | 580 | return res; 581 | } 582 | }; 583 | 584 | /* Get area of a nondegenerate triangle, with sides a, b, c */ 585 | template 586 | T getAreaTriangle (T a, T b, T c) { 587 | T p = (a + b + c)/2.0; 588 | return sqrt (p * (p - a) * (p - b) * (p - c)); 589 | } 590 | 591 | int main (void) { 592 | ios_base::sync_with_stdio(false); 593 | 594 | return 0; 595 | } 596 | -------------------------------------------------------------------------------- /math/geometry/point.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define mk make_pair 6 | #define pb push_back 7 | #define fi first 8 | #define se second 9 | 10 | typedef pair ii; 11 | typedef long long ll; 12 | const double EPS = 1e-9; 13 | const double PI = acos(-1.0); 14 | 15 | template 16 | class Point { 17 | public: 18 | T x, y; 19 | 20 | Point () { } 21 | 22 | Point (T x, T y) : x(x), y(y) {} 23 | 24 | bool operator == (const Point &b) const { 25 | return (abs (x - b.x) < EPS and abs (y - b.y) < EPS); 26 | } 27 | 28 | bool operator < (const Point &b) const { 29 | return ((x < b.x) or ((x == b.x) and y < b.y)); 30 | } 31 | 32 | //Produto vetorial 33 | // p^q = |p|*|q|*sin(ang) ang: directed ang from p to q(-PI < ang <= PI) 34 | // p^q = 0 => ang = 0 or PI, p and q are colinear 35 | // p^q > 0 => 0 < ang < PI / p^q < 0 => -PI < ang < 0 36 | // p^q = directed area of paralelogram formed by vectors p and q 37 | // dist point p to line ab = ||ab^p|| / ||ab|| 38 | T operator ^ (const Point &b) const { 39 | return (this->x * b.y) - (this->y * b.x); 40 | } 41 | 42 | //Produto escalar 43 | // p*q = |p|*|q|*cos(ang) ang: inner ang (0 <= ang < PI) 44 | // p*q = 0 => ang = 90 / p*q > 0 => ang < 90 / p*q < 0 => ang > 90 45 | // p*p = |p|^2 => |p| = sqrt(p*p) 46 | T operator * (const Point &b) const { 47 | return (this->x * b.x) + (this->y * b.y); 48 | } 49 | 50 | Point operator * (T k) const { 51 | return Point (x*k, y*k); 52 | } 53 | 54 | Point operator / (T k) const { 55 | return Point (x/k, y/k); 56 | } 57 | 58 | Point operator + (const Point &b) const { 59 | return Point (x + b.x, y + b.y); 60 | } 61 | 62 | Point operator - (const Point &b) const { 63 | return Point (x - b.x, y - b.y); 64 | } 65 | 66 | T len2 () const { 67 | return x*x + y*y; 68 | } 69 | 70 | T len () const { 71 | return sqrt (x*x + y*y); 72 | } 73 | 74 | T dpp2 (const Point &b) const { 75 | return ((*this)-b)*((*this)-b); 76 | } 77 | 78 | T dpp (const Point &b) const { 79 | return ((*this)-b).len(); 80 | } 81 | 82 | Point rotaciona (T ang) const { 83 | T c = cos(ang), s = sin(ang); 84 | T X = x*c - y*s; 85 | T Y = x*s + y*c; 86 | return Point(X,Y); 87 | } 88 | }; 89 | 90 | int main (void) { 91 | ios_base::sync_with_stdio(false); 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /math/karatsuba.cpp: -------------------------------------------------------------------------------- 1 | /*O(n^log2(3)) or O(n1.58) 2 | https://codeforces.com/blog/entry/74209 is faster 3 | 4 | Queremos calcular a multiplicacao de polinomio A*B 5 | 6 | n = maximo entre tamanho do polinomio a e b. Fazer n ser uma potencia de 2 para ficar mais simples 7 | mid = n/2 8 | 9 | Dividir o polinomio P em 2 partes, p1 e p0. p0 eh a metade com os coeficientes das potencias de 0 ateh mid-1 e p1 eh a metade com os coeficientes das potencias de mid ateh n-1. 10 | 11 | A = a1*x^mid + a0 12 | B = b1*x^mid + b0 13 | 14 | assim A*B = (a1*x^mid + a0) * (b1*x^mid + b0) = a0*b0 + (a1*b0 + a0*b1)*x^mid + a1*b1*x^n (**formula1**) 15 | 16 | podemos calcular a0*b0 e a1*b1. Note que esses polinomios tem a metade do tamanho dos originais(mid). 17 | Vamos chamar f0 = a0*b0 e f1 = a1*b1 18 | 19 | E agora calculamos E = (a0+a1)*(b0+b1). (a0+a1) e (b0+b1) possuem tamanho mid tambem. 20 | 21 | A resposta para A*B pode ser escrita da forma: 22 | 23 | f0 + f1*x^n + (E - f0 - f1)*x^mid 24 | 25 | Por que isso esta certo? 26 | f0 + f1*x^n + (E - f0 - f1)*x^mid, substituindo f0 e f1 27 | (a0*b0) + (a1*b1)*x^n + (E - (a0*b0) - (a1*b1))*x^mid, substituindo E 28 | (a0*b0) + (a1*b1)*x^n + ((a0+a1)*(b0+b1) - (a0*b0) - (a1*b1))*x^mid, abrindo as multiplicacoes 29 | (a0*b0) + (a1*b1)*x^n + (a0*b0 + a0*b1 + a1*b0 + a1*b1 - (a0*b0) - (a1*b1))*x^mid, simplificando 30 | (a0*b0) + (a1*b1)*x^n + (a0*b1 + a1*b0)*x^mid, e isso eh igual a A*B escrito em **formula1** acima 31 | 32 | Complexidade: 33 | Para o problema de tamanho n, fazemos 3 chamadas para um problema menor de tamanho mid=n/2, (a0*b0, a1*b1 e (a0+a1)*(b0+b1)): 34 | T(n) = 3*T(n/2) + O(n) 35 | pelo teorema do mestre a complexidade eh O(n^log2(3)) 36 | */ 37 | 38 | #include 39 | 40 | using namespace std; 41 | 42 | template 43 | void mult(vector &a, vector &b, const int n, vector &res) { 44 | if(n <= 64) { 45 | for(int i = 0; i < n; i++) 46 | for(int j = 0; j < n; j++) 47 | res[i+j] += a[i]*b[j]; 48 | return; 49 | } 50 | 51 | int mid = n/2; 52 | vector _a(mid), _b(mid); 53 | vector E(n); 54 | 55 | mult(a, b, mid, res); // f0 = a0*b0 56 | 57 | for(int i = 0; i < mid; i++) { // a1, b1 58 | _a[i] = a[i+mid]; 59 | _b[i] = b[i+mid]; 60 | } 61 | mult(_a, _b, mid, E); // f1 = a1*b1 62 | for(int i = 0; i < n; i++) 63 | res[i+n] = E[i]; // *= x^n 64 | 65 | for(int i = 0; i < mid; i++) { // (a0+a1), (b0+b1) 66 | _a[i] = a[i] + a[i+mid]; 67 | _b[i] = b[i] + b[i+mid]; 68 | } 69 | fill(E.begin(), E.end(), 0); 70 | mult(_a, _b, mid, E); // E = (a0+a1)*(b0+b1) 71 | 72 | for(int i = 0; i < mid; i++) { // (E-f0-f1)*x^mid 73 | const T tmp = res[i+mid]; 74 | res[i+mid] += E[i] - res[i] - res[i+n]; 75 | res[i+mid+mid] += E[i+mid] - tmp - res[i+n+mid]; 76 | } 77 | } 78 | 79 | template 80 | void mult(const vector &a, const vector &b, vector &res) { 81 | int n = 1; 82 | while(n < (int)max(a.size(), b.size())) n <<= 1; 83 | vector _a(a.begin(), a.end()); 84 | vector _b(b.begin(), b.end()); 85 | _a.resize(n, 0); _b.resize(n, 0); 86 | 87 | res.resize(2*n); 88 | fill(res.begin(), res.end(), 0); 89 | mult(_a, _b, n, res); 90 | } 91 | 92 | 93 | int main(void) { 94 | ios_base::sync_with_stdio(false); 95 | int T; cin >> T; 96 | while(T--) { 97 | int n; cin >> n; 98 | n++; 99 | vector a(n, 0), b(n, 0), res; 100 | for(int i = 0; i < n; i++) 101 | cin >> a[i]; 102 | for(int i = 0; i < n; i++) 103 | cin >> b[i]; 104 | 105 | mult(a, b, res); 106 | 107 | for(int i = 0; i < 2*n-1; i++) 108 | cout << res[i] << " \n"[i==2*n-2]; 109 | } 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /math/millerRabin_pollardRho.cpp: -------------------------------------------------------------------------------- 1 | // https://cp-algorithms.com/algebra/primality_tests.html#deterministic-version 2 | // https://cp-algorithms.com/algebra/factorization.html#implementation_1 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define pb push_back 8 | #define eb emplace_back 9 | #define mk make_pair 10 | #define fi first 11 | #define se second 12 | 13 | typedef long long ll; 14 | typedef __int128 LL; 15 | typedef pair ii; 16 | const int INF = 0x3f3f3f3f; 17 | const double PI = acos(-1.0); 18 | 19 | ll exp(LL x, ll y, ll mod) { 20 | ll r = 1; 21 | x %= mod; 22 | 23 | while(y) { 24 | if (y&1) 25 | r = (x*r)%mod; 26 | x = (x*x)%mod; 27 | y >>= 1; 28 | } 29 | 30 | return r; 31 | } 32 | 33 | // Fermat's little theorem: a^(n-1) = 1 % n 34 | // n-1 = 2^s * d 35 | // a^(n-1) = 1 mod n 36 | // a^(2^s * d) - 1 = 0 mod n 37 | // (a^(2^(s-1)d + 1)(a^(2^(s-2)d + 1)...(a^(2^d) + 1)(a^(2^d) - 1) = 0 mod n 38 | // If none of these terms are equal 0 mod n, we are sure that n is not a prime. 39 | // Otherwise n is **likely** a prime, need to try with other bases a. 40 | // O(log3(n)) 41 | bool checkComposite(ll n, ll a, ll d, int s) { 42 | ll x = exp(a, d, n); 43 | 44 | if (x == 1 or x == n-1) 45 | return false; 46 | 47 | for (int r = 1; r < s; r++) { 48 | x = ((LL)x*x)%n; 49 | if (x == n-1) 50 | return false; 51 | } 52 | 53 | return true; 54 | } 55 | 56 | // Returns true if n is prime, else returns false. 57 | // O(k*log3(n)), k = number of bases tested. 58 | bool millerRabin(ll n) { 59 | if (n < 2) 60 | return false; 61 | 62 | // n-1 = (2^s)*d; 63 | int s = 0; 64 | ll d = n-1; 65 | while((d&1) == 0) { 66 | d >>= 1; 67 | s++; 68 | } 69 | 70 | // Checking all base a <= 2ln(n)^2 is enough 71 | // But for a 64 bit integer, the first 12 primes work. 72 | // For 32 bit integer the first 4 primes work {2, 3, 5, 7}. 73 | for (int a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) { 74 | if (n == a) 75 | return true; 76 | if (checkComposite(n, a, d, s)) 77 | return false; 78 | } 79 | return true; 80 | } 81 | 82 | // O( sqrt(sqrt(n)) ) 83 | ll rho(const ll n, const ll x0=2, const ll c=1) { 84 | if (n == 1) return 1; 85 | 86 | auto f = [&c, &n](LL x) { 87 | return (x*x + c)%n; 88 | }; 89 | 90 | auto mult = [&n](LL a, ll b) { 91 | return (a*b)%n; 92 | }; 93 | 94 | ll x = x0; 95 | ll g = 1; 96 | ll q = 1; 97 | ll xs, y; 98 | 99 | int m = 128; 100 | int l = 1; 101 | while(g == 1) { 102 | y = x; 103 | for (int i = 1; i < l; i++) 104 | x = f(x); 105 | 106 | int k = 0; 107 | while (k < l && g == 1) { 108 | xs = x; 109 | for (int i = 0; i < m && i < l-k; i++) { 110 | x = f(x); 111 | q = mult(q, abs(y-x)); 112 | } 113 | g = gcd(q, n); 114 | k += m; 115 | } 116 | 117 | l *= 2; 118 | } 119 | 120 | if (g == n) { 121 | do { 122 | xs = f(xs); 123 | g = gcd(abs(xs - y), n); 124 | } while(g == 1); 125 | } 126 | 127 | return g; 128 | } 129 | 130 | int main (void) { 131 | ios_base::sync_with_stdio(false); 132 | 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /math/ntt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define eb emplace_back 7 | #define mk make_pair 8 | #define fi first 9 | #define se second 10 | 11 | typedef long long ll; 12 | typedef pair ii; 13 | const int INF = 0x3f3f3f3f; 14 | const double PI = acos(-1.0); 15 | 16 | // root is a r**c, r is nth root of unity r**n = 1 % mod and r**k != 1 % mod for 1 <= k < n 17 | // r**c is (2**k)th root of unity and can be used to calculate ntt for polynomial of size 2**k 18 | // mod must be of form: mod = 2**k * c + 1 19 | 20 | const int N = 2e5 + 5; 21 | const int mod = 998244353; 22 | const int root = 363395222; 23 | const int root_1 = 704923114; 24 | const int root_pw = 1 << 19; 25 | 26 | int inverse(int x, int mod) { 27 | int y = mod - 2; 28 | int ret = 1, a = x; 29 | 30 | while(y > 0) { 31 | if(y&1) 32 | ret = (1LL * ret * a)%mod; 33 | 34 | a = (1LL * a * a)%mod; 35 | y>>=1; 36 | } 37 | 38 | return ret; 39 | } 40 | 41 | // a, b => coefs to multiply, res => resulting coefs 42 | // // a[0], b[0], res[0] = coef x^0 43 | // // Doesnt work with negative coefs 44 | void fft(vector & a, bool invert) { 45 | int n = a.size(); 46 | 47 | for (int i = 1, j = 0; i < n; i++) { 48 | int bit = n >> 1; 49 | for (; j & bit; bit >>= 1) 50 | j ^= bit; 51 | j ^= bit; 52 | 53 | if (i < j) 54 | swap(a[i], a[j]); 55 | } 56 | 57 | for (int len = 2; len <= n; len <<= 1) { 58 | int wlen = invert ? root_1 : root; 59 | for (int i = len; i < root_pw; i <<= 1) 60 | wlen = (int)(1LL * wlen * wlen % mod); 61 | 62 | for (int i = 0; i < n; i += len) { 63 | int w = 1; 64 | for (int j = 0; j < len / 2; j++) { 65 | int u = a[i+j], v = (int)(1LL * a[i+j+len/2] * w % mod); 66 | a[i+j] = u + v < mod ? u + v : u + v - mod; 67 | a[i+j+len/2] = u - v >= 0 ? u - v : u - v + mod; 68 | w = (int)(1LL * w * wlen % mod); 69 | } 70 | } 71 | } 72 | 73 | if (invert) { 74 | int n_1 = inverse(n, mod); 75 | for (int & x : a) 76 | x = (int)(1LL * x * n_1 % mod); 77 | } 78 | } 79 | 80 | void multiply(const vector &a, const vector &b, vector &res) { 81 | vector fa(a.begin(), a.end()), fb(b.begin(), b.end()); 82 | int n = 1; 83 | while (n < (int) max(a.size(), b.size())) n <<= 1; 84 | n <<= 1; 85 | fa.resize (n), fb.resize (n); 86 | 87 | fft(fa, false), fft (fb, false); 88 | for (int i = 0; i < n; ++i) 89 | fa[i] = 1LL * fa[i] * fb[i] % mod; 90 | fft (fa, true); 91 | res = fa; 92 | } 93 | 94 | int main (void) { 95 | ios_base::sync_with_stdio(false); 96 | 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /math/ntt_constants.txt: -------------------------------------------------------------------------------- 1 | // mod = 2**k * c + 1 2 | // ASSERT: root_pw(2**k) > 2*N 3 | 4 | const int mod = 7340033; 5 | const int root = 5; // 2**c -> (2**k)th root 6 | const int root_1 = 4404020; // root inverse 7 | const int root_pw = 1 << 20; // 2**k (note: 2**k must be greater than N) 8 | 9 | const int N = 2e5 + 5; 10 | const int mod = 998244353; 11 | const int root = 15311432; 12 | const int root_1 = 469870224; 13 | const int root_pw = 1 << 23; 14 | 15 | const int N = 2e5 + 5; 16 | const int mod = 998244353; 17 | const int root = 363395222; 18 | const int root_1 = 704923114; 19 | const int root_pw = 1 << 19; 20 | 21 | -------------------------------------------------------------------------------- /math/pre_ntt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define eb emplace_back 7 | #define mk make_pair 8 | #define fi first 9 | #define se second 10 | 11 | typedef long long ll; 12 | typedef pair ii; 13 | const int INF = 0x3f3f3f3f; 14 | const double PI = acos(-1.0); 15 | 16 | const int N = 1e5 + 5; 17 | ll mod, n, c; 18 | int vis[N]; 19 | vector v; 20 | 21 | void crivo() { 22 | for(int i = 2; i < N; i++) 23 | if(!vis[i]) 24 | for(int j = i + i; j < N; j += i) 25 | vis[j] = 1; 26 | } 27 | 28 | int pot(ll x, ll y, int mod) { 29 | int ret = 1; 30 | ll a = x; 31 | 32 | while(y > 0) { 33 | if(y&1) 34 | ret = (a * ret)%mod; 35 | 36 | a = (a * a)%mod; 37 | y>>=1; 38 | } 39 | 40 | return ret; 41 | } 42 | 43 | void find_nth_root(int mod) { 44 | crivo(); 45 | 46 | int n = mod - 1; 47 | int m = sqrt(n) + 2; 48 | 49 | for(int i = 2; i < m; i++) 50 | if(!vis[i] and n%i == 0) 51 | v.pb(n/i); 52 | 53 | // find if i**k != 1 for 1 <= k < mod - 1 = 2**k * c 54 | // just need to try (mod - 1)/prime_is_(mod-1) because of cicles 55 | for(int i = 2; i < mod; i++) { 56 | bool f = true; 57 | for(auto d : v) 58 | if(pot(i, d, mod) == 1) 59 | f = false; 60 | 61 | if(f) { 62 | // if i is (mod - 1)th root, i**c is (2**k)th root 63 | // now we can use i**c as root of ntt for polynomial of size 2**k (order 2**k - 1) 64 | cout << "r: " << i << endl; 65 | cout << "root = r**c: " << pot(i, c, mod) << endl; 66 | cout << "root_1 = r**-c: " << pot(i, (c*(mod - 2))%(mod-1), mod) << endl; 67 | return; 68 | } 69 | } 70 | } 71 | 72 | void find_pw(int n) { 73 | int pw = 1; 74 | int k = 0; 75 | 76 | while(pw < n) { 77 | pw <<= 1; 78 | k++; 79 | } 80 | 81 | c = (mod - 1)/pw; 82 | 83 | cout << "pw: " << pw << " root_pw: 1<<" << k << endl; 84 | cout << "(mod-1)%pw: " << (mod-1)%pw << " (mod-1)/pw = c: " << c << endl; 85 | 86 | // mod must be of form mod = 2**k * c + 1 87 | assert((mod-1)%pw == 0); 88 | } 89 | 90 | int main (void) { 91 | ios_base::sync_with_stdio(false); 92 | 93 | cout << "mod: "; 94 | cin >> mod; 95 | cout << "\nn: "; 96 | cin >> n; 97 | 98 | cout << "mod: " << mod << endl; 99 | 100 | find_pw(2*n); 101 | 102 | find_nth_root(mod); 103 | 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /math/stirling1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define eb emplace_back 7 | #define mk make_pair 8 | #define fi first 9 | #define se second 10 | 11 | typedef long long ll; 12 | typedef pair ii; 13 | const int INF = 0x3f3f3f3f; 14 | const double PI = acos(-1.0); 15 | 16 | const int N = 2e5 + 5; 17 | const int mod = 998244353; 18 | const int root = 363395222; 19 | const int root_1 = 786627976; 20 | const int root_pw = 1 << 19; 21 | 22 | int inverse(int x, int mod) { 23 | int y = mod - 2; 24 | int ret = 1, a = x; 25 | 26 | while(y > 0) { 27 | if(y&1) 28 | ret = (1LL * ret * a)%mod; 29 | 30 | a = (1LL * a * a)%mod; 31 | y>>=1; 32 | } 33 | 34 | return ret; 35 | } 36 | 37 | void fft(vector & a, bool invert) { 38 | int n = a.size(); 39 | 40 | for (int i = 1, j = 0; i < n; i++) { 41 | int bit = n >> 1; 42 | for (; j & bit; bit >>= 1) 43 | j ^= bit; 44 | j ^= bit; 45 | 46 | if (i < j) 47 | swap(a[i], a[j]); 48 | } 49 | 50 | for (int len = 2; len <= n; len <<= 1) { 51 | int wlen = invert ? root_1 : root; 52 | for (int i = len; i < root_pw; i <<= 1) 53 | wlen = (int)(1LL * wlen * wlen % mod); 54 | 55 | for (int i = 0; i < n; i += len) { 56 | int w = 1; 57 | for (int j = 0; j < len / 2; j++) { 58 | int u = a[i+j], v = (int)(1LL * a[i+j+len/2] * w % mod); 59 | a[i+j] = u + v < mod ? u + v : u + v - mod; 60 | a[i+j+len/2] = u - v >= 0 ? u - v : u - v + mod; 61 | w = (int)(1LL * w * wlen % mod); 62 | } 63 | } 64 | } 65 | 66 | if (invert) { 67 | int n_1 = inverse(n, mod); 68 | for (int & x : a) 69 | x = (int)(1LL * x * n_1 % mod); 70 | } 71 | } 72 | 73 | void multiply(const vector &a, const vector &b, vector &res) { 74 | vector fa(a.begin(), a.end()), fb(b.begin(), b.end()); 75 | int n = 1; 76 | while (n < (int) max(a.size(), b.size())) n <<= 1; 77 | n <<= 1; 78 | fa.resize (n), fb.resize (n); 79 | 80 | fft(fa, false), fft (fb, false); 81 | for (int i = 0; i < n; ++i) 82 | fa[i] = 1LL * fa[i] * fb[i] % mod; 83 | fft (fa, true); 84 | res = fa; 85 | } 86 | 87 | // Stirling Number of The First Kind: Count permutations according to their number of cycles 88 | // s(n, k): Count the number of permutations of n elements with k disjoint cycles 89 | // s(n, k): Number of permutations such that for N elements exactly A records are present from front 90 | // record -> number that is greater than previous 91 | // (x)**(n) = x * (x + 1) * (x + 2) ... (x + n - 1) = sum(k=0, n){ s(n, k) * x**k } 92 | // Then the coeficient ak of x**k on (x)**(n) = s(n, k). Use fft to calculate (x)**(n) 93 | // s(n + 1, k) = s(n, k - 1) - n * s(n, k); s(0, 0) = 1 and s(n, 0) = s(0, n) = 0 94 | // O(nn * log(nn)) 95 | vector s[N]; 96 | int stirling1(int n, int k) { 97 | int nn = 1; 98 | while(nn < n) nn <<= 1; 99 | 100 | // (i + x) 101 | for(int i = 0; i < n; ++i) { 102 | s[i].push_back(i); 103 | s[i].push_back(1); 104 | } 105 | 106 | // fill the rest with (1) 107 | for(int i = n; i < nn; ++i) { 108 | s[i].push_back(1); 109 | } 110 | 111 | // multiply all s[i] 112 | // each time first half of s is multiplied by corresponding value on second half 113 | // then we can consider only first half of s on next iterations 114 | for(int j = nn; j > 1; j >>= 1){ // j: size of s on this iteration 115 | int hn = j >> 1; // half size of s 116 | for(int i = 0; i < hn; ++i) { 117 | multiply(s[i], s[i + hn], s[i]); // multiply value on first half with second half 118 | } 119 | } 120 | 121 | return s[0][k]; 122 | } 123 | 124 | ll pot(ll x, ll y) { 125 | ll ret = 1LL; 126 | ll a = x; 127 | 128 | while(y > 0) { 129 | if(y&1) 130 | ret = (ret * a)%mod; 131 | 132 | a = (a * a)%mod; 133 | y >>= 1; 134 | } 135 | 136 | return ret; 137 | } 138 | 139 | ll fat[N]; 140 | ll choose(ll n, ll k) { 141 | if(k > n) return 0; 142 | 143 | ll ret = fat[n]; 144 | 145 | ret = (ret * pot(fat[n-k], mod - 2))%mod; 146 | ret = (ret * pot(fat[k], mod - 2))%mod; 147 | 148 | return ret; 149 | } 150 | 151 | // Count the number of permutations such that the number of records from the 152 | // front is A and the number of records from the back is B 153 | // record: a value that is greater than previous ones in some direction 154 | ll solve(ll n, ll a, ll b) { 155 | ll res = choose(a + b - 2, a - 1); 156 | res *= stirling1(n - 1, a + b - 2); 157 | res %= mod; 158 | 159 | return res; 160 | } 161 | 162 | int main (void) { 163 | ios_base::sync_with_stdio(false); 164 | 165 | fat[0] = 1; 166 | for(int i = 1; i < N; i++) 167 | fat[i] = (1LL * fat[i-1] * i)%mod; 168 | 169 | return 0; 170 | } 171 | -------------------------------------------------------------------------------- /sites.md: -------------------------------------------------------------------------------- 1 | - Problem Set 2 | 3 | [Codeforces Ladders (A2OJ)](https://a2oj.com/ladders) 4 | 5 | [SPOJ](http://www.spoj.com) 6 | 7 | ------------ 8 | 9 | - Long Contest 10 | 11 | [Codechef](https://www.codechef.com) 12 | 13 | [HackerRank](https://www.hackerrank.com/contests) 14 | 15 | ------------ 16 | 17 | - Short Contest 18 | 19 | [Codeforces](https://www.codeforces.com) 20 | 21 | [AtCoder](https://atcoder.jp) 22 | 23 | [CSAcademy](https://csacademy.com) 24 | -------------------------------------------------------------------------------- /strings/FiniteStateMachinePrefixFunction.cpp: -------------------------------------------------------------------------------- 1 | /* Finite State Machine with prefix function for regular strings 2 | 3 | A[i][j]: i-> current state 4 | j-> new character to be appended 5 | contains the next state 6 | 7 | F[i][j]: i-> current state 8 | j-> new sequence of the string to be appended 9 | contains the next state 10 | 11 | K[i][j]: i-> current state 12 | j-> new sequence of the string to be appended 13 | contains the occurences of the pattern 14 | Problem: 15 | how many times the pattern p (containing only 'a' or 'b') 16 | appears at some fibonnaci string fk 17 | 18 | Fibbonaci string: f0 = '' 19 | f1 = 'a' 20 | f2 = 'b' 21 | fi = fi-2 + fi-1 22 | */ 23 | 24 | #include 25 | 26 | using namespace std; 27 | 28 | #define pb push_back 29 | #define mk make_pair 30 | #define fi first 31 | #define se second 32 | 33 | typedef long long ll; 34 | typedef pair ii; 35 | const int INF = 0x3f3f3f3f; 36 | const double PI = acos(-1.0); 37 | 38 | const int N = 1e3 + 5; 39 | int pi[N], k; 40 | ll mod = 1e9 + 9; 41 | vector p; 42 | 43 | void pre () { 44 | p.pb(-1); 45 | 46 | for (int i = 2; i <= (int)p.size(); i++) { 47 | pi[i] = pi[i-1]; 48 | while (pi[i] > 0 and p[pi[i]] != p[i-1]) 49 | pi[i] = pi[pi[i]]; 50 | 51 | if (p[pi[i]] == p[i-1]) 52 | pi[i]++; 53 | } 54 | } 55 | 56 | const int M = 1e4 + 4; 57 | ll A[N][2]; 58 | ll F[N][M], K[N][M]; 59 | 60 | int main (void) { 61 | string str; 62 | cin >> str >> k; 63 | 64 | for (int i = 0; i < (int)str.length(); i++) 65 | p.pb(str[i] - 'a'); 66 | pre (); 67 | 68 | for (int i = 0; i <= 1; i++) 69 | A[0][i] = (p[0] == i); 70 | 71 | int n = p.size(); 72 | for (int i = 1; i < n; i++) 73 | for (int j = 0; j <= 1; j++) 74 | if (j == p[i]) 75 | A[i][j] = i + 1; 76 | else 77 | A[i][j] = A[pi[i]][j]; 78 | 79 | for (int i = 0; i < n; i++) { 80 | F[i][0] = i; 81 | F[i][1] = A[i][0]; 82 | F[i][2] = A[i][1]; 83 | 84 | K[i][0] = 0; 85 | K[i][1] = (F[i][1] == (int)str.size()); 86 | K[i][2] = (F[i][2] == (int)str.size()); 87 | } 88 | 89 | for (int j = 3; j <= k; j++) { 90 | for (int i = 0; i < n; i++) { 91 | int x = F[i][j-2]; 92 | F[i][j] = F[x][j-1]; 93 | 94 | K[i][j] = K[i][j-2] + K[x][j-1]; 95 | K[i][j] %= mod; 96 | } 97 | } 98 | 99 | cout << K[0][k] << endl; 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /strings/Kmp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | border = proper prefix that is suffix 3 | p[i] = length of longest border of prefix of length i, s[0...i-1] 4 | */ 5 | 6 | #include 7 | 8 | using namespace std; 9 | 10 | #define pb push_back 11 | #define mk make_pair 12 | #define fi first 13 | #define se second 14 | 15 | typedef long long ll; 16 | typedef pair ii; 17 | const int INF = 0x3f3f3f3f; 18 | const double PI = acos(-1.0); 19 | 20 | const int N = 1e6 + 6; 21 | int pi[N]; 22 | string p, t; 23 | 24 | void pre () { 25 | p += '#'; 26 | 27 | pi[0] = pi[1] = 0; 28 | for (int i = 2; i <= (int)p.size(); i++) { 29 | pi[i] = pi[i-1]; 30 | 31 | while (pi[i] > 0 and p[pi[i]] != p[i-1]) 32 | pi[i] = pi[pi[i]]; 33 | 34 | if (p[pi[i]] == p[i-1]) 35 | pi[i]++; 36 | } 37 | } 38 | 39 | void report (int at) { 40 | 41 | } 42 | 43 | void KMP () { 44 | pre (); 45 | 46 | int k = 0; 47 | int m = p.size() - 1; 48 | 49 | for (int i = 0; i < (int)t.size(); i++) { 50 | while (k > 0 and p[k] != t[i]) 51 | k = pi[k]; 52 | 53 | if (p[k] == t[i]) 54 | k++; 55 | if (k == m) 56 | report (i - m + 1); 57 | } 58 | 59 | } 60 | 61 | int main (void) { 62 | ios_base::sync_with_stdio(false); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /strings/Manacher.cpp: -------------------------------------------------------------------------------- 1 | /* Manacher’s algorithm O(N), time and memory, algorithm to find 2 | * longest palindromic substring 3 | * 4 | * Transform initial string t into s, 5 | * puting separators between characters 6 | * 7 | * Build vector p[], where p[i] is the length of the 8 | * palindrome centered at s[i] 9 | * 10 | * Works for both, odd and even length 11 | * s: # a # b # a # # a # a # 12 | * p: 0 1 0 3 0 1 0 0 1 2 1 0 13 | * 14 | * p built in O(N) using the fact that elements can be simetric 15 | * given some center and p[center]: 16 | * If we are in i and center c, i_mirror = c - (i - c), if p[i_mirror] 17 | * fits in center + p[center], p[i] is p[i_mirror], else we need to 18 | * check real value of p[i] 19 | * If we call the border center + p[center], r. Its easy to see 20 | * r is only increased, achieving the O(N) time complexity 21 | * 22 | * Longest palindromic substring is the maximum element in p 23 | * 24 | * */ 25 | 26 | #include 27 | 28 | using namespace std; 29 | 30 | #define pb push_back 31 | #define mk make_pair 32 | #define fi first 33 | #define se second 34 | 35 | typedef long long ll; 36 | typedef pair ii; 37 | const int INF = 0x3f3f3f3f; 38 | const double PI = acos(-1.0); 39 | 40 | const int N = 1e6 + 5; 41 | int p[2*N + 2]; 42 | 43 | int main (void) { 44 | ios_base::sync_with_stdio(false); 45 | 46 | string s, t; cin >> t; 47 | s += "#"; 48 | for (auto c : t) { 49 | s += c; 50 | s += '#'; 51 | } 52 | 53 | int n = s.size(); 54 | int c = 0, r = 0; 55 | for (int i = 0; i < n; i++) { 56 | int i_mirror = c - (i - c); 57 | 58 | if (i <= r) 59 | p[i] = min (p[i_mirror], r - i); 60 | else 61 | p[i] = 0; 62 | 63 | while (i - 1 - p[i] >= 0 and i + 1 + p[i] < n and s[i + 1 + p[i]] == s[i - 1 - p[i]]) { 64 | p[i]++; 65 | } 66 | 67 | if (i + p[i] > r) { 68 | c = i; 69 | r = i + p[i]; 70 | } 71 | } 72 | 73 | int len = 0, center = 0; 74 | for (int i = 0; i < n; i++) 75 | if (p[i] > len) { 76 | len = p[i]; 77 | center = i; 78 | } 79 | 80 | /* not tested */ 81 | string res; 82 | for (int i = 0; i < n; i++) 83 | if (i >= center - len and i <= center + len and s[i] != '#') 84 | res += s[i]; 85 | /* */ 86 | 87 | cout << len << endl; 88 | cout << res << endl; 89 | 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /strings/SuffixAutomaton.cpp: -------------------------------------------------------------------------------- 1 | /* Build Suffix Automata of string S 2 | * aciclic graph where nodes are called states and edges 3 | * between states have char labels, a path in the automata 4 | * listing all edge labels defines a substring, all substrings 5 | * are defined exactly once in the automata 6 | * 7 | * build time and space: O(N = length(S)) 8 | * 9 | * Endpos(T): set of all positions where T ends in S 10 | * if u is suffix of w -> Endpos(w) C Endpos(u), 11 | * Endpos(w) is contained inside Endpos(u) 12 | * else -> Endpos(w) /\ Endpos(u) = {} 13 | * 14 | * Same class: Endpos(u) == Endpos(v) 15 | * sort all strings of same class, the of lengths difference between 16 | * consective strings is 1, and one string is suffix of all others 17 | * with greatest length 18 | * 19 | * Number of states is equal to the number of endpos classes 20 | * 21 | * Links 22 | * w is the longest string in state v. 23 | * suffix link of v is the state that contains the longest suffix of w 24 | * that is in different endpos class 25 | * Properties: 26 | * minlen(v) = len(link(v)) + 1 27 | * endpos(v) C (endpos(link(v)) 28 | * 29 | * 30 | * Construction of Suffix Automaton: 31 | * 1: It is online, we construct by adding a single character to our 32 | * previous string 33 | * 2: Initial state: id = 0, len = 0, link = -1 34 | * 3: Add a single caracter c to the end of the current line 35 | * 4: Last is the state that corresponds to the entire line 36 | * before adding the symbol (initially Last = 0) 37 | * 5: When adding a new caracter we will make state Cur 38 | * adding a new character increase the number of endpos classes by 39 | * at least 1 as no previous substring can end at the position of c 40 | * len(Cur) = len(Last) + 1 41 | * Finding suffix-link and modifing the tree, loop: 42 | * Find suffix of Last with edge with label c, (it points to suffix of Cur). 43 | * 1: we are at node Last, we add edge between Last and Cur with label c 44 | * and move to suffix link of Last, until we reach state 0 or if edge 45 | * with label c already exists 46 | * 2: if at some state P, edge with label c already exists, we stop at P. 47 | * Q is the state connected to P via c. Q needs to be suffix of Cur. 48 | * - if len(P) + 1 == len(Q), link(Cur) = Q, break 49 | * - otherwise we have to create a clone of state Q with everithing 50 | * the same, except for len(Clone) = len(p) + 1 ans assing 51 | * link(Cur) = Clone, assigin edge with label c, fora all 52 | * P in suffix tree to Clone, break 53 | * 3: if 2 never happened, we are at dummy state -1, assing link(Cur) = 0 54 | * 55 | * 56 | * Summary: 57 | * Contains_substring 58 | * Number_of_different_substrings 59 | * Kth_smallest_distinct_substring 60 | * Smallest_cyclic_shift 61 | * Shortest_not_included_string 62 | * Longest_2_commom_substring 63 | * Number_of_occurrences 64 | * Position_first_occurrence 65 | * Position_of_all_occurrences 66 | * in_a_not_in_b 67 | * */ 68 | 69 | #include 70 | 71 | using namespace std; 72 | 73 | #define pb push_back 74 | #define mk make_pair 75 | #define fi first 76 | #define se second 77 | 78 | typedef long long ll; 79 | const int INF = 0x3f3f3f3f; 80 | 81 | struct state { 82 | int len; // Length of Longest Suffix 83 | int link; // Suffix Link of the state 84 | int fpos; // First element in endpos of this state, endpos.begin() 85 | map next; 86 | }; 87 | 88 | const int N = 3e5 + 5; 89 | state st[2*N]; 90 | int sz, last; 91 | 92 | void sa_init() { 93 | for (int i = 0; i < 2*N; i++) 94 | st[i].next.clear(); 95 | last = 0; 96 | sz = 1; 97 | st[0].len = 0; 98 | st[0].link = -1; 99 | st[0].fpos = -1; 100 | } 101 | 102 | void sa_extend (char c) { 103 | int cur = sz++; 104 | st[cur].len = st[last].len + 1; 105 | st[cur].fpos = st[cur].len - 1; //fpos 106 | int p; 107 | for (p = last; p != -1 and !st[p].next.count(c); p = st[p].link) 108 | st[p].next[c] = cur; 109 | if (p == -1) 110 | st[cur].link = 0; 111 | else { 112 | int q = st[p].next[c]; 113 | if (st[p].len + 1 == st[q].len) 114 | st[cur].link = q; 115 | else { 116 | int clone = sz++; 117 | st[clone].len = st[p].len + 1; 118 | st[clone].next = st[q].next; 119 | st[clone].link = st[q].link; 120 | st[clone].fpos = st[q].fpos; //fpos 121 | for (; p != -1 and st[p].next[c] == q; p = st[p].link) 122 | st[p].next[c] = clone; 123 | st[q].link = st[cur].link = clone; 124 | } 125 | } 126 | last = cur; 127 | } 128 | 129 | void sa_build() { 130 | sa_init(); 131 | string s; cin >> s; 132 | for (int i = 0; i < (int)s.size(); i++) 133 | sa_extend(s[i]); 134 | } 135 | 136 | /* Just walk through the automata */ 137 | namespace Contains_substring { 138 | bool go (string &p) { 139 | int at = 0; 140 | 141 | for (auto c : p) 142 | if (!st[at].next.count(c)) 143 | return false; 144 | else 145 | at = st[at].next[c]; 146 | 147 | return true; 148 | } 149 | 150 | void main () { 151 | sa_build(); 152 | 153 | int q; cin >> q; 154 | while (q--) { 155 | string p; cin >> p; 156 | 157 | if (go(p)) 158 | cout << 'Y' << endl; 159 | else 160 | cout << 'N' << endl; 161 | } 162 | } 163 | } 164 | 165 | /* Find the number of diffrent paths with is equal to the number 166 | * of different substrings */ 167 | namespace Number_of_different_substrings { 168 | ll dp[2*N]; 169 | 170 | ll go (int at) { 171 | ll &r = dp[at]; 172 | if (r != -1) return r; 173 | 174 | r = 1; 175 | for (auto it : st[at].next) 176 | r += go (it.se); 177 | 178 | return r; 179 | } 180 | 181 | void main () { 182 | sa_build(); 183 | memset (dp, -1, sizeof dp); 184 | // decrease 1 to disconsider empty substring 185 | cout << go (0) - 1LL << endl; 186 | } 187 | } 188 | 189 | /* Pick smallest possible edge that we can 190 | * go to next state */ 191 | namespace Kth_smallest_distinct_substring { 192 | void go (int at, int k) { 193 | if (k <= 0) return; 194 | 195 | for (auto it : st[at].next) { 196 | ll dp = Number_of_different_substrings::dp[it.se]; 197 | 198 | if (dp >= k) { 199 | cout << it.fi; 200 | go (it.se, k - 1); 201 | return; 202 | } else { 203 | k -= dp; 204 | } 205 | } 206 | } 207 | 208 | void main () { 209 | sa_build(); 210 | memset (Number_of_different_substrings::dp, -1, 211 | sizeof Number_of_different_substrings::dp); 212 | Number_of_different_substrings::go(0); 213 | 214 | int T; cin >> T; 215 | while (T--) { 216 | int k; cin >> k; 217 | // Print kth smallest substring 218 | go (0, k); 219 | cout << endl; 220 | } 221 | } 222 | } 223 | 224 | /* Suffix automaton over s + s, find smallest substring with len = len(s) */ 225 | namespace Smallest_cyclic_shift { 226 | int slen; 227 | void sa_build() { 228 | sa_init(); 229 | string s; cin >> s; 230 | slen = s.size(); 231 | s += s; 232 | for (int i = 0; i < (int)s.size(); i++) 233 | sa_extend(s[i]); 234 | } 235 | 236 | // Find maximun length we can get starting by state "at" 237 | int dp[2*N]; 238 | int go (int at) { 239 | int &r = dp[at]; 240 | if (r != -1) return r; 241 | 242 | r = 1; 243 | for (auto it : st[at].next) 244 | r = max (r, go (it.se) + 1); 245 | return r; 246 | } 247 | 248 | void solve (int at, int len) { 249 | if (!len) { 250 | // one based 251 | cout << (st[at].fpos - slen + 1) + 1 << endl; 252 | return; 253 | } 254 | 255 | // pass though edges in label order 256 | for (auto it : st[at].next) 257 | if (dp[it.se] >= len - 1) { 258 | solve (it.se, len - 1); 259 | return; 260 | } 261 | } 262 | 263 | void main () { 264 | sa_build(); 265 | memset (dp, -1, sizeof dp); 266 | go (0); 267 | solve (0, slen); 268 | } 269 | } 270 | 271 | /* Shorstest string (in length), then if multople has same length 272 | * get the lexicographicaly smallest 273 | * */ 274 | namespace Shortest_not_included_string { 275 | // find minimun not included string we can find 276 | // from this state 277 | int dp[2*N]; 278 | int go (int at) { 279 | int &r = dp[at]; 280 | if (r != INF) return r; 281 | 282 | if (st[at].next.size() < 'Z' - 'A' + 1) 283 | return r = 1; 284 | 285 | for (auto it : st[at].next) 286 | r = min (r, go(it.se) + 1); 287 | 288 | return r; 289 | } 290 | 291 | // find small lexicographically 292 | // print answer 293 | void solve (int at) { 294 | for (char c = 'A'; c <= 'Z'; c++) { 295 | if (!st[at].next.count(c)) { 296 | cout << c; 297 | return; 298 | } 299 | } 300 | 301 | for (char c = 'A'; c <= 'Z'; c++) { 302 | int nx = st[at].next[c]; 303 | if (dp[at] == dp[nx] + 1) { 304 | cout << c; 305 | solve (nx); 306 | return; 307 | } 308 | } 309 | } 310 | 311 | void main () { 312 | sa_build(); 313 | memset (dp, INF, sizeof dp); 314 | go (0); 315 | solve (0); 316 | cout << endl; 317 | } 318 | } 319 | 320 | /* Longest commom prefix of two substrings 321 | * 322 | * b will be the base string, other string will be processed 323 | * 324 | * Find longest suffix of processed string that apears as 325 | * a prefix [0 ... i] of b, for each i, using suffix links 326 | * answer is the maximum in all steaps 327 | * */ 328 | namespace Longest_2_commom_substring { 329 | 330 | void main () { 331 | sa_build(); 332 | string b; cin >> b; 333 | 334 | int res = 0; 335 | int at = 0, len = 0; 336 | 337 | for (auto c : b) { 338 | while (at and !st[at].next.count(c)) { 339 | at = st[at].link; 340 | len = st[at].len; 341 | // in this case len will always decrease because 342 | // len[link[p]] + 1 = minimal string length in class p 343 | // so len[link[p]] < length we got at this time increasing, 344 | // so this is the length of some string in at[j] class 345 | } 346 | 347 | // found some suffix with edge with label c 348 | // otherwise we just got empty suffix 349 | if (st[at].next.count(c)) { 350 | at = st[at].next[c]; 351 | len++; 352 | } 353 | res = max (res, len); 354 | } 355 | 356 | cout << res << endl; 357 | } 358 | } 359 | 360 | /* Find substrings number of occurrences 361 | * 362 | * Same class have the same number of occurrences 363 | * 364 | * Algorithm: count number of times a state is prefix 365 | * of a suffix, (all suffixes are terminal states, terminal 366 | * state is the last state and his link path, suffixes of it) 367 | * */ 368 | namespace Number_of_occurrences { 369 | int dp[2*N]; 370 | int terminal[2*N]; 371 | 372 | // mark terminal states 373 | void mark () { 374 | memset (terminal, 0, sizeof terminal); 375 | int at = last; 376 | 377 | while (at != -1) { 378 | terminal[at] = true; 379 | at = st[at].link; 380 | } 381 | } 382 | 383 | // calculate 384 | int go (int at) { 385 | int &r = dp[at]; 386 | if (r != -1) return r; 387 | 388 | r = terminal[at]; 389 | 390 | for (auto it : st[at].next) 391 | r += go (it.se); 392 | 393 | return r; 394 | } 395 | 396 | // get answer for a pattern p 397 | int get (string &p) { 398 | int at = 0; 399 | 400 | for (auto c : p) { 401 | if (!st[at].next.count(c)) { 402 | // pattern not found 403 | return 0; 404 | } else { 405 | at = st[at].next[c]; 406 | } 407 | } 408 | 409 | return dp[at]; 410 | } 411 | 412 | void main () { 413 | sa_build(); 414 | mark(); 415 | memset (dp, -1, sizeof dp); 416 | go (0); 417 | 418 | int q; cin >> q; 419 | while (q--) { 420 | string p; cin >> p; 421 | cout << get (p) << endl; 422 | } 423 | } 424 | } 425 | 426 | /* Note: Another way of doing it is: getting the state, then calculate 427 | * using dynamic programming the biggest length to the last node, answer 428 | * is text.length() - dp[at] + 1 429 | * 430 | * Find the state of the substring, 431 | * answer is the first element of endpos (fpos) - length of substring + 1 432 | * */ 433 | namespace Position_first_occurrence { 434 | 435 | int get (string &p) { 436 | int at = 0; 437 | 438 | for (auto c : p) { 439 | if (!st[at].next.count(c)) { 440 | return -1; 441 | } else { 442 | at = st[at].next[c]; 443 | } 444 | } 445 | 446 | return st[at].fpos - p.size() + 1; 447 | } 448 | 449 | void main() { 450 | sa_build(); 451 | 452 | int q; cin >> q; 453 | while (q--) { 454 | string p; cin >> p; 455 | cout << get(p) << endl; 456 | } 457 | } 458 | } 459 | 460 | /* OBS: Total number of occurrences can be calculated this way too 461 | * 462 | * Position of all occurrences of a pathen p in a text, 463 | * O(sizeof(text) + number of occurrences of the patterns), 464 | * 465 | * Build the tree of edges from link[node] to node, find state 466 | * corresponding to the pattern, go through the tree (go from at to 467 | * next means, at is suffix of next, endpos(next) is countained in endpos(at) 468 | * and size(endpos(at)) = size(endpos(next)) + 1), them set of first occurrence of 469 | * all states are the position of all occurrences of the pattern 470 | * */ 471 | namespace Position_all_occurrences { 472 | vector res; 473 | vector g[2*N]; 474 | string p; 475 | 476 | /* Build suffix link tree */ 477 | void build_tree () { 478 | for (int i = 1; i <= last; i++) 479 | g[st[i].link].pb(i); 480 | } 481 | 482 | /* Use bfs to avoid memory limit */ 483 | void go (int beg) { 484 | queue q; 485 | q.push(beg); 486 | 487 | while (q.size()) { 488 | int at = q.front(); 489 | q.pop(); 490 | // index of pattern p as suffix of the first occurrence 491 | // of state next 492 | res.pb(st[at].fpos - p.size() + 1); 493 | 494 | for (auto next : g[at]) 495 | q.push(next); 496 | } 497 | } 498 | 499 | /* get the state, to go throgh tree next*/ 500 | void get () { 501 | int at = 0; 502 | 503 | for (auto c : p) 504 | if (!st[at].next.count(c)) 505 | return; 506 | else 507 | at = st[at].next[c]; 508 | 509 | go (at); 510 | } 511 | 512 | void main () { 513 | sa_build(); 514 | build_tree(); 515 | 516 | int q; cin >> q; 517 | while (q--) { 518 | res.clear(); 519 | cin >> p; 520 | get(); 521 | 522 | cout << res.size() << endl; 523 | for (auto it : res) 524 | cout << it << " "; 525 | cout << endl; 526 | } 527 | } 528 | } 529 | 530 | /*number of differente substrings in a that are not 531 | * in b*/ 532 | namespace in_a_not_in_b { 533 | void sa_build() { 534 | sa_init(); 535 | string a, b; cin >> a >> b; 536 | string s = a + '#' + b + '$'; 537 | for (int i = 0; i < (int)s.size(); i++) 538 | sa_extend(s[i]); 539 | } 540 | 541 | int a[2*N], b[2*N]; 542 | 543 | // a[at] marks if state at belongs to string a 544 | int finda(int at) { 545 | int &r = a[at]; 546 | if (r != -1) return r; 547 | r = 0; 548 | 549 | for (auto next : st[at].next) { 550 | if (next.fi == '#') r = 1; 551 | if (finda(next.se)) r = 1; 552 | } 553 | 554 | return r; 555 | } 556 | 557 | // a[at] marks if state at belongs to string b 558 | int findb(int at) { 559 | int &r = b[at]; 560 | if (r != -1) return r; 561 | r = 0; 562 | 563 | for (auto next : st[at].next) { 564 | if (next.fi == '#') continue; 565 | if (next.fi == '$') r = 1; 566 | if (findb(next.se)) r = 1; 567 | } 568 | 569 | return r; 570 | } 571 | 572 | // just count how many strings are in a but no in b 573 | ll dp[2*N]; 574 | ll go(int at) { 575 | ll &r = dp[at]; 576 | if (r != -1) return r; 577 | 578 | r = a[at] and !b[at]; 579 | for (auto next : st[at].next) 580 | r += go(next.se); 581 | 582 | return r; 583 | } 584 | 585 | void main() { 586 | sa_build(); 587 | memset(a, -1, sizeof a); 588 | finda(0); 589 | memset(b, -1, sizeof b); 590 | findb(0); 591 | memset(dp, -1, sizeof dp); 592 | cout << go(0) << endl; 593 | } 594 | } 595 | 596 | int main (void) { 597 | ios_base::sync_with_stdio(false); 598 | 599 | return 0; 600 | } 601 | -------------------------------------------------------------------------------- /strings/SuffixAutomaton_base.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | const int INF = 0x3f3f3f3f; 12 | 13 | struct state { 14 | int len; // Length of Longest Suffix 15 | int link; // Suffix Link of the state 16 | int fpos; // First element in endpos of this state, endpos.begin() 17 | map next; 18 | }; 19 | 20 | const int N = 3e5 + 5; 21 | state st[2*N]; 22 | int sz, last; 23 | 24 | void sa_init() { 25 | for (int i = 0; i < 2*N; i++) 26 | st[i].next.clear(); 27 | last = 0; 28 | sz = 1; 29 | st[0].len = 0; 30 | st[0].link = -1; 31 | st[0].fpos = -1; 32 | } 33 | 34 | void sa_extend (char c) { 35 | int cur = sz++; 36 | st[cur].len = st[last].len + 1; 37 | st[cur].fpos = st[cur].len - 1; //fpos 38 | int p; 39 | for (p = last; p != -1 and !st[p].next.count(c); p = st[p].link) 40 | st[p].next[c] = cur; 41 | if (p == -1) 42 | st[cur].link = 0; 43 | else { 44 | int q = st[p].next[c]; 45 | if (st[p].len + 1 == st[q].len) 46 | st[cur].link = q; 47 | else { 48 | int clone = sz++; 49 | st[clone].len = st[p].len + 1; 50 | st[clone].next = st[q].next; 51 | st[clone].link = st[q].link; 52 | st[clone].fpos = st[q].fpos; //fpos 53 | for (; p != -1 and st[p].next[c] == q; p = st[p].link) 54 | st[p].next[c] = clone; 55 | st[q].link = st[cur].link = clone; 56 | } 57 | } 58 | last = cur; 59 | } 60 | 61 | void sa_build() { 62 | sa_init(); 63 | string s; cin >> s; 64 | for (int i = 0; i < (int)s.size(); i++) 65 | sa_extend(s[i]); 66 | } 67 | 68 | int main (void) { 69 | ios_base::sync_with_stdio(false); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /strings/SuffixAutomaton_class.cpp: -------------------------------------------------------------------------------- 1 | /* Build Suffix Automata of string S 2 | * aciclic graph where nodes are called states and edges 3 | * between states have char labels, a path in the automata 4 | * listing all edge labels defines a substring, all substrings 5 | * are defined exactly once in the automata 6 | * 7 | * build time and space: O(N = length(S)) 8 | * 9 | * Endpos(T): set of all positions where T ends in S 10 | * if u is suffix of w -> Endpos(w) C Endpos(u) 11 | * else -> Endpos(w) /\ Endpos(u) = {} 12 | * 13 | * Same class: Endpos(u) == Endpos(v) 14 | * sort all strings of same class, the of lengths difference between 15 | * consective strings is 1, and one string is suffix of all others 16 | * with greatest length 17 | * 18 | * Number of states is equal to the number of endpos classes 19 | * 20 | * Links 21 | * w is the longest string in state v. 22 | * suffix link of v is the state that contains the longest suffix of w 23 | * that is in different endpos class 24 | * Properties: 25 | * minlen(v) = len(link(v)) + 1 26 | * endpos(v) C (endpos(link(v)) 27 | * 28 | * 29 | * Construction of Suffix Automaton: 30 | * 1: It is online, we construct by adding a single character to our 31 | * previous string 32 | * 2: Initial state: id = 0, len = 0, link = -1 33 | * 3: Add a single caracter c to the end of the current line 34 | * 4: Last is the state that corresponds to the entire line 35 | * before adding the symbol (initially Last = 0) 36 | * 5: When adding a new caracter we will make state Cur 37 | * adding a new character increase the number of endpos classes by 38 | * at least 1 as no previous substring can end at the position of c 39 | * len(Cur) = len(Last) + 1 40 | * Finding suffix-link and modifing the tree, loop: 41 | * Find suffix of Last with edge with label c, (it points to suffix of Cur). 42 | * 1: we are at node Last, we add edge between Last and Cur with label c 43 | * and move to suffix link of Last, until we reach state 0 or if edge 44 | * with label c already exists 45 | * 2: if at some state P, edge with label c already exists, we stop at P. 46 | * Q is the state connected to P via c. Q needs to be suffix of Cur. 47 | * - if len(P) + 1 == len(Q), link(Cur) = Q, break 48 | * - otherwise we have to create a clone of state Q with everithing 49 | * the same, except for len(Clone) = len(p) + 1 ans assing 50 | * link(Cur) = Clone, assigin edge with label c, fora all 51 | * P in suffix tree to Clone, break 52 | * 3: if 2 never happened, we are at dummy state -1, assing link(Cur) = 0 53 | * */ 54 | 55 | #include 56 | 57 | using namespace std; 58 | 59 | #define pb push_back 60 | #define mk make_pair 61 | #define fi first 62 | #define se second 63 | 64 | typedef long long ll; 65 | const int INF = 0x3f3f3f3f; 66 | 67 | const int N = 1e4 + 5; 68 | 69 | struct SuffixAutomaton { 70 | struct state { 71 | int len; // Length of Longest Suffix 72 | int link; // Suffix Link of the state 73 | int fpos; // First element in endpos of this state, endpos.begin() 74 | map next; 75 | }; 76 | 77 | state st[2*N]; 78 | int sz, last; 79 | 80 | SuffixAutomaton () {} 81 | 82 | void sa_init() { 83 | for (int i = 0; i < 2*N; i++) 84 | st[i].next.clear(); 85 | last = 0; 86 | sz = 1; 87 | st[0].len = 0; 88 | st[0].link = -1; 89 | st[0].fpos = -1; 90 | } 91 | 92 | void sa_extend (char c) { 93 | int cur = sz++; 94 | st[cur].len = st[last].len + 1; 95 | st[cur].fpos = st[cur].len - 1; //fpos 96 | int p; 97 | for (p = last; p != -1 and !st[p].next.count(c); p = st[p].link) 98 | st[p].next[c] = cur; 99 | if (p == -1) 100 | st[cur].link = 0; 101 | else { 102 | int q = st[p].next[c]; 103 | if (st[p].len + 1 == st[q].len) 104 | st[cur].link = q; 105 | else { 106 | int clone = sz++; 107 | st[clone].len = st[p].len + 1; 108 | st[clone].next = st[q].next; 109 | st[clone].link = st[q].link; 110 | st[clone].fpos = st[q].fpos; //fpos 111 | for (; p != -1 and st[p].next[c] == q; p = st[p].link) 112 | st[p].next[c] = clone; 113 | st[q].link = st[cur].link = clone; 114 | } 115 | } 116 | last = cur; 117 | } 118 | 119 | void sa_build() { 120 | sa_init(); 121 | string s; cin >> s; 122 | for (int i = 0; i < (int)s.size(); i++) 123 | sa_extend(s[i]); 124 | } 125 | }; 126 | 127 | /* Longest commom prefix of k substrings 128 | * 129 | * b will be the base string, other k-1 will be processed 130 | * 131 | * Find longest suffix of each other string that apears as 132 | * a prefix [0 ... i] of b, for each i, using suffix links 133 | * Take the mininum of each processed string at each step, 134 | * (it is the maximum commom suffix for each prefix i), 135 | * answer is the maximum in all steaps 136 | * */ 137 | namespace Longest_k_commom_substring { 138 | const int K = 10; 139 | SuffixAutomaton sa[K]; 140 | int at[K], len[K]; 141 | 142 | void main () { 143 | int k; cin >> k; k--; 144 | memset (at, 0, sizeof at); 145 | memset (len, 0, sizeof len); 146 | for (int i = 0; i < k; i++) 147 | sa[i].sa_build(); 148 | 149 | string b; cin >> b; 150 | if (!k) { 151 | cout << b.size() << endl; 152 | return; 153 | } 154 | 155 | int res = 0; 156 | for (auto c : b) { 157 | int r = INF; 158 | for (int j = 0; j < k; j++) { 159 | while (at[j] and !sa[j].st[at[j]].next.count(c)) { 160 | at[j] = sa[j].st[at[j]].link; 161 | len[j] = sa[j].st[at[j]].len; 162 | // in this case len will always decrease because 163 | // len[link[p]] + 1 = minimal string length in class p 164 | // so len[link[p]] < length we got at this time increasing, 165 | // so this is the length of some string in at[j] class 166 | } 167 | 168 | // found some suffix with edge with label c 169 | // otherwise we just got empty suffix 170 | if (sa[j].st[at[j]].next.count(c)) { 171 | at[j] = sa[j].st[at[j]].next[c]; 172 | len[j]++; 173 | } 174 | r = min (r, len[j]); 175 | } 176 | res = max (res, r); 177 | } 178 | 179 | cout << res << endl; 180 | } 181 | } 182 | 183 | int main (void) { 184 | ios_base::sync_with_stdio(false); 185 | 186 | return 0; 187 | } 188 | -------------------------------------------------------------------------------- /strings/Z.cpp: -------------------------------------------------------------------------------- 1 | /* {0, if i = 0 2 | z[i] = {length longest commom prefix of s and s[i...n-1] 3 | */ 4 | 5 | #include 6 | 7 | using namespace std; 8 | 9 | #define pb push_back 10 | #define mk make_pair 11 | #define fi first 12 | #define se second 13 | 14 | typedef long long ll; 15 | typedef pair ii; 16 | const int INF = 0x3f3f3f3f; 17 | const double PI = acos(-1.0); 18 | 19 | const int N = 2e5 + 5; 20 | string s; 21 | int z[N]; 22 | 23 | void go () { 24 | int l = 0, r = 0; 25 | int n = s.size(); 26 | memset (z, 0, sizeof z); 27 | 28 | for (int i = 1; i < n; i++) { 29 | if (i <= r) 30 | z[i] = min (z[i-l], r - i + 1); 31 | while (z[i] + i < n and s[z[i] + i] == s[z[i]]) 32 | z[i]++; 33 | if (r < i + z[i] - 1) { 34 | l = i; 35 | r = i + z[i] - 1; 36 | } 37 | } 38 | } 39 | 40 | int main (void) { 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /strings/hash.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | 13 | ll md (ll x, ll mod) { 14 | x %= mod; 15 | if (x < 0) 16 | return x + mod; 17 | return x; 18 | } 19 | 20 | struct Hash { 21 | const ll base = 31; 22 | ll mod, *h, *pot; 23 | string s; 24 | 25 | Hash () {} 26 | 27 | void build (string s, ll mod) { 28 | this->mod = mod; 29 | this->s = s; 30 | h = new ll [s.size() + 2]; 31 | pot = new ll [s.size() + 2]; 32 | 33 | h[0] = s[0] - 'a'; 34 | for (int i = 1; i < (int)s.size(); i++) 35 | h[i] = (h[i-1]*base + s[i] - 'a')%mod; 36 | 37 | pot[0] = 1LL; 38 | for (int i = 1; i < (int)s.size(); i++) 39 | pot[i] = (pot[i-1] * base)%mod; 40 | } 41 | 42 | ll query (int l, int r) { 43 | ll R = h[r], L = 0; 44 | 45 | if (l) 46 | L = (h[l-1] * pot[r - l + 1])%mod; 47 | 48 | return md (R - L, mod); 49 | } 50 | 51 | } h[2]; 52 | 53 | // returns if s[i, i + ilen - 1] is lexicographically smaller than s[j, j + jlen - 1] 54 | // not tested if ilen != jlen 55 | bool comp (string &s, int i, int ilen, int j, int jlen) { 56 | int bot = 0, top = min (ilen, jlen) - 1; 57 | int id = -1; 58 | 59 | while (bot <= top) { 60 | int mid = (bot + top)>>1; 61 | 62 | ii pi = ii(h[0].query(i, i + mid), h[1].query(i, i + mid)); 63 | ii pj = ii(h[0].query(j, j + mid), h[1].query(j, j + mid)); 64 | if (pi == pj) { 65 | bot = mid + 1; 66 | id = mid; 67 | } else { 68 | top = mid - 1; 69 | } 70 | } 71 | 72 | if (id == min (ilen, jlen) - 1) { 73 | if (ilen != jlen) 74 | return ilen < jlen; 75 | return i < j; 76 | } 77 | 78 | return s[i + id + 1] < s[j + id + 1]; 79 | } 80 | 81 | const ll mod[2] = {1000000007, 1000000009}; 82 | -------------------------------------------------------------------------------- /strings/trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | struct Trie { 16 | int cnt, word; 17 | map m; 18 | 19 | Trie () { 20 | word = cnt = 0; 21 | m.clear(); 22 | } 23 | 24 | void add (const string &s, int i) { 25 | cnt++; 26 | if (i == (int)s.size()) { 27 | word++; 28 | return; 29 | } 30 | 31 | if (!m.count(s[i])) 32 | m[s[i]] = Trie(); 33 | 34 | m[s[i]].add(s, i + 1); 35 | } 36 | 37 | bool remove (const string &s, int i) { 38 | if (i == (int)s.size()) { 39 | if (word) { 40 | cnt--; 41 | word--; 42 | return true; 43 | } 44 | return false; 45 | } 46 | 47 | if (!m.count(s[i])) 48 | return false; 49 | 50 | if (m[s[i]].remove(s, i + 1) == true) { 51 | cnt--; 52 | return true; 53 | } 54 | 55 | return false; 56 | } 57 | 58 | bool count (const string &s, int i) { 59 | if (i == (int)s.size()) 60 | return word; 61 | 62 | if (!m.count(s[i])) 63 | return false; 64 | 65 | return m[s[i]].count(s, i + 1); 66 | } 67 | 68 | bool count_prefix (const string &s, int i) { 69 | if (word) return true; 70 | 71 | if (i == (int)s.size()) 72 | return false; 73 | 74 | if (!m.count(s[i])) 75 | return false; 76 | 77 | return m[s[i]].count_prefix(s, i + 1); 78 | } 79 | 80 | bool is_prefix (const string &s, int i) { 81 | if (i == (int)s.size()) 82 | return cnt; 83 | 84 | if (!m.count(s[i])) 85 | return false; 86 | 87 | return m[s[i]].is_prefix(s, i + 1); 88 | } 89 | 90 | void add (const string &s) { 91 | add (s, 0); 92 | } 93 | 94 | bool remove (const string &s) { 95 | return remove(s, 0); 96 | } 97 | 98 | bool count (const string &s) { 99 | return count(s, 0); 100 | } 101 | 102 | // return if trie countains a string that is prefix os s 103 | // trie has 123, query 12345 returns true 104 | // trie has 12345, query 123 returns false 105 | bool count_prefix (const string &s) { 106 | return count_prefix(s, 0); 107 | } 108 | 109 | // return if s is prefix of some string countained in trie 110 | // trie has 12345, query 123 returns true 111 | // trie has 123, query 12345 returns false 112 | bool is_prefix (const string &s) { 113 | return is_prefix(s, 0); 114 | } 115 | 116 | } T; 117 | -------------------------------------------------------------------------------- /tester.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | 5 | class srcFile: 6 | def __init__(self, src, ex) : 7 | self.src = src 8 | self.ex = ex 9 | self.compile() 10 | self.wr = [] 11 | 12 | def compile(self): 13 | cmd = "g++ " + self.src + " -O2 -o " + self.ex 14 | print(cmd) 15 | os.system(cmd) 16 | 17 | def run(self, case, out, flags=""): 18 | cmd = "./" + self.ex + " <" + case + " >" + out + " " + flags 19 | os.system(cmd) 20 | 21 | def report(self): 22 | if(len(self.wr) == 0): 23 | print(self.src + " OK!") 24 | else: 25 | print(self.src + " Wrong cases("+ str(len(self.wr))+ "): ", end="") 26 | for c in self.wr: 27 | print(c, end=" ") 28 | print() 29 | 30 | if len(sys.argv) < 3: 31 | exit(0) 32 | PMAX = int(sys.argv[1]) 33 | N = int(sys.argv[2]) 34 | 35 | with open("files.json") as json_file: 36 | data = json.load(json_file) 37 | 38 | sol = [] 39 | for i in range (len(data["solution"])): 40 | src = srcFile(data["solution"][i], "Test/sol" + str(i)) 41 | sol.append(src) 42 | brute = srcFile(data["brute"], "Test/brute") 43 | gen = srcFile(data["generator"], "Test/gen") 44 | 45 | for i in range(N): 46 | case = "Test/case" + str(i) 47 | cmd = "./" + gen.ex + " >" + case + " " + str(PMAX) 48 | os.system(cmd) 49 | 50 | brute.run(case, "Test/brute.out", str(PMAX)) 51 | 52 | print("Case " , i); 53 | 54 | for s in sol: 55 | s.run(case, "Test/sol.out") 56 | if(os.system("diff Test/brute.out Test/sol.out") != 0): 57 | s.wr.append(i) 58 | 59 | for s in sol: 60 | s.report() 61 | -------------------------------------------------------------------------------- /tmux.conf: -------------------------------------------------------------------------------- 1 | # Enable 256 colors, https://github.com/tmux/tmux/wiki/FAQ 2 | set -g default-terminal "screen-256color" 3 | 4 | -------------------------------------------------------------------------------- /trick/ConvexHullTrick.cpp: -------------------------------------------------------------------------------- 1 | /* dp[i] = min j>i { a[j]*b[i] + dp[j] } 2 | varj atual <= varj antigo 3 | (optional) vari atual >= vari antigo 4 | 5 | vari -> query (x da linha) 6 | varj -> slope da linha 7 | */ 8 | 9 | #include 10 | 11 | using namespace std; 12 | 13 | #define pb push_back 14 | #define mk make_pair 15 | #define fi first 16 | #define se second 17 | 18 | typedef long long ll; 19 | typedef pair ii; 20 | const double PI = acos(-1.0); 21 | 22 | const int N = 1e5 + 5; 23 | int n; 24 | ll a[N], b[N]; 25 | ll dp[N]; 26 | 27 | set > s; 28 | 29 | void add (double a, double b, int id) { 30 | set >::iterator it = s.end(); 31 | 32 | while (it != s.begin()) { 33 | it--; 34 | 35 | int j = it->se; 36 | double c = ::a[j], d = dp[j]; 37 | 38 | double x = (d - b)/(a - c); 39 | 40 | if (x > it->fi) { 41 | s.insert(mk(x, id)); 42 | 43 | it = s.end(); it--; 44 | while (it->se != id) { 45 | s.erase(it); 46 | it = s.end(); it--; 47 | } 48 | 49 | break; 50 | } 51 | } 52 | } 53 | 54 | int main (void) { 55 | ios_base::sync_with_stdio(false); 56 | 57 | cin >> n; 58 | for (int i = 0; i < n; i++) 59 | cin >> a[i]; 60 | for (int i = 0; i < n; i++) 61 | cin >> b[i]; 62 | 63 | const double INF = DBL_MAX; 64 | s.insert(mk(-INF, n-1)); 65 | for (int i = n - 2; i >= 0; i--) { 66 | double x = b[i]; 67 | 68 | set >::iterator it = s.upper_bound (mk(x, 0)); 69 | it--; 70 | 71 | int j = it->se; 72 | 73 | dp[i] = a[j] * b[i] + dp[j]; 74 | 75 | add (a[i], dp[i], i); 76 | } 77 | 78 | cout << dp[0] << endl; 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /trick/ConvexHullTrick1.cpp: -------------------------------------------------------------------------------- 1 | /* dp[i] = min j a[j+1]: put new line in the end 5 | * 6 | * code example for problem: http://www.spoj.com/problems/ACQUIRE/ 7 | * */ 8 | #include 9 | 10 | using namespace std; 11 | 12 | #define pb push_back 13 | #define eb emplace_back 14 | #define mk make_pair 15 | #define fi first 16 | #define se second 17 | 18 | typedef long long ll; 19 | typedef pair ii; 20 | const int INF = 0x3f3f3f3f; 21 | const double PI = acos(-1.0); 22 | 23 | const int N = 5e4 + 4; 24 | ll n, w[N], h[N]; 25 | ll dp[N]; 26 | 27 | double inter(ii p1, ii p2) { 28 | ll a = p1.fi; 29 | ll b = p1.se; 30 | 31 | ll c = p2.fi; 32 | ll d = p2.se; 33 | 34 | return (double)(d-b)/(double)(a-c); 35 | } 36 | 37 | int main (void) { 38 | ios_base::sync_with_stdio(false); 39 | 40 | cin >> n; 41 | vector ve; 42 | for(int i = 0; i < n; i++) { 43 | int a, b; cin >> a >> b; 44 | ve.eb(a, b); 45 | } 46 | sort(ve.begin(), ve.end()); 47 | 48 | w[0] = ve[0].fi; 49 | h[0] = ve[0].se; 50 | n = 0; 51 | 52 | for(int i = 1; i < (int)ve.size(); i++) { 53 | ll W = ve[i].fi; 54 | ll H = ve[i].se; 55 | 56 | while(n >= 0 and h[n] <= H) 57 | n--; 58 | 59 | n++; 60 | w[n] = W; 61 | h[n] = H; 62 | } 63 | n++; 64 | 65 | for(int i = 0; i < n - 1; i++) 66 | assert(w[i] <= w[i+1]); 67 | for(int i = 0; i < n - 1; i++) 68 | assert(h[i] > h[i+1]); 69 | 70 | deque > s; 71 | deque >::iterator it1, it2; 72 | const double inf = 1e18; 73 | s.eb(ii(h[0], 0), inf); 74 | for(int i = 0; i < n; i++) { 75 | while(w[i] > s.begin()->se) 76 | s.pop_front(); 77 | 78 | ll a = s.begin()->fi.fi; 79 | ll b = s.begin()->fi.se; 80 | dp[i] = a*w[i] + b; 81 | 82 | while(s.size() > 1) { 83 | it2 = --s.end(); 84 | it1 = it2; it1--; 85 | 86 | if(inter(it1->fi, it2->fi) < inter(it1->fi, ii(h[i+1], dp[i]))) { 87 | break; 88 | } else { 89 | s.pop_back(); 90 | } 91 | } 92 | s.rbegin()->se = inter(s.rbegin()->fi, ii(h[i+1], dp[i])); 93 | s.eb(ii(h[i+1], dp[i]), inf); 94 | } 95 | 96 | cout << dp[n-1] << endl; 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /trick/DivideConquer.cpp: -------------------------------------------------------------------------------- 1 | /* Divide & Conquer Trick 2 | * dp[m][i] = min k= 0 it's always true 19 | * 20 | * proof: 21 | * assume a < b and opta > optb 22 | * so: 23 | * dp[optb] + c[optb][a] > dp[opta] + c[opta][a] optb must have minimum value for dpb 24 | * dp[opta] + c[opta][b] > dp[optb] + c[optb][b] opta must have mininum value for dpa 25 | * 26 | * dp[optb] + c[optb][a] > dp[opta] + c[opta][a] 27 | * -dp[optb] + c[opta][b] > -dp[opta] + c[optb][b] 28 | * 29 | * c[optb][a] + c[opta][b] > c[opta][a] + c[optb][b] 30 | * contradition: 31 | * optb < opta < a < b (opti < i) 32 | * c[optb][a] + c[opta][b] < c[optb][b] + c[opta][a] 33 | * 34 | * Algorithm: 35 | * go(m, l, r, optl, optr) 36 | * if(l > r) return 37 | * i = (l+r)/2 38 | * dp[m][i] = INF 39 | * for(optl <= k <= min(optr, i-1)) 40 | * if(dp[m-1][k]+c[k][i] < dp[m][i]) 41 | * opt = k 42 | * dp[m][i] = dp[m-1][k]+c[k][i] 43 | * 44 | * go(m, l, i-1, optl, opt) 45 | * go(m, i+1, r, opt, optr) 46 | * 47 | * code example for problem: http://codeforces.com/contest/321/problem/E 48 | * */ 49 | #include 50 | 51 | using namespace std; 52 | 53 | #define pb push_back 54 | #define eb emplace_back 55 | #define mk make_pair 56 | #define fi first 57 | #define se second 58 | 59 | typedef long long ll; 60 | typedef pair ii; 61 | const int INF = 0x3f3f3f3f; 62 | const double PI = acos(-1.0); 63 | 64 | const int N = 4123, M = 812; 65 | int n, m, u[N][N], c[N][N]; 66 | int dp[M][N]; 67 | 68 | int cost(int a, int b) { 69 | int ret = c[b][b]; 70 | 71 | if(a) { 72 | ret -= c[a-1][b] + c[b][a-1]; 73 | ret += c[a-1][a-1]; 74 | } 75 | 76 | return ret; 77 | } 78 | 79 | void go(int m, int l, int r, int optl, int optr) { 80 | if(l > r) return; 81 | int i = (l + r)>>1; 82 | 83 | int opt = optl; 84 | dp[m][i] = INF; 85 | for(int k = optl; k <= optr and k < i; k++) { 86 | int at = dp[m-1][k] + (cost(k+1, i)>>1); 87 | if(at < dp[m][i]) { 88 | dp[m][i] = at; 89 | opt = k; 90 | } 91 | } 92 | 93 | go(m, l, i - 1, optl, opt); 94 | go(m, i + 1, r, opt, optr); 95 | } 96 | 97 | int main (void) { 98 | 99 | scanf("%d %d", &n, &m); 100 | for(int i = 1; i <= n; i++) 101 | for(int j = 1; j <= n; j++) { 102 | char ch; 103 | getchar(); 104 | ch = getchar(); 105 | u[i][j] = ch - '0'; 106 | } 107 | 108 | for(int j = 1; j <= n; j++) 109 | c[0][j] = c[0][j-1] + u[0][j]; 110 | 111 | for(int i = 1; i <= n; i++) { 112 | int at = 0; 113 | for(int j = 1; j <= n; j++) { 114 | at += u[i][j]; 115 | c[i][j] = c[i-1][j] + at; 116 | } 117 | } 118 | 119 | for(int i = 1; i <= n; i++) 120 | dp[0][i] = INF; 121 | dp[0][0] = 0; 122 | 123 | for(int i = 1; i <= m; i++) 124 | go(i, 1, n, 0, n-1); 125 | 126 | printf("%d\n", dp[m][n]); 127 | 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /trick/MosAlgorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | const double E = exp(1); 15 | 16 | const int N = 1e5 + 5; 17 | int n; 18 | int a[N]; 19 | int m; 20 | vector > v; 21 | const int S = sqrt(N); 22 | int res[N]; 23 | int ans = 0; 24 | 25 | void tira (int i) { 26 | /* 27 | Tirar a[i] 28 | */ 29 | } 30 | 31 | void add (int i) { 32 | /* 33 | Colocar a[i] 34 | */ 35 | } 36 | 37 | void go () { 38 | int l = 0, r = 0; 39 | 40 | add(0); 41 | 42 | for (int i = 0; i < v.size(); i++) { 43 | ii p = v[i].fi; 44 | int id = v[i].se; 45 | 46 | while (r < p.se) { 47 | r++; 48 | add(r); 49 | } 50 | 51 | while (r > p.se) { 52 | tira(r); 53 | r--; 54 | } 55 | 56 | 57 | while (l < p.fi) { 58 | tira(l); 59 | l++; 60 | } 61 | 62 | while (l > p.fi) { 63 | l--; 64 | add(l); 65 | } 66 | 67 | res[id] = ans; 68 | } 69 | 70 | } 71 | 72 | bool comp (pair p1, pair p2) { 73 | ii x1, x2; 74 | x1 = p1.fi; 75 | x2 = p2.fi; 76 | if (x1.fi / S != x2.fi / S) return x1.fi / S < x2.fi / S; 77 | return x1.se > x2.se; 78 | } 79 | 80 | int main (void) { 81 | ios_base::sync_with_stdio(false); 82 | 83 | cin >> n; 84 | 85 | for (int i = 0; i < n; i++) 86 | cin >> a[i]; 87 | 88 | cin >> m; 89 | for (int i = 0; i < m; i++) { 90 | int l, r; cin >> l >> r; 91 | l--; r--; 92 | v.pb(mk(mk(l, r), i)); 93 | } 94 | 95 | sort(v.begin(), v.end(), comp); 96 | 97 | go(); 98 | 99 | for (int i = 0; i < m; i++) { 100 | cout << res[i] << endl; 101 | } 102 | 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /trick/mo_tree.cpp: -------------------------------------------------------------------------------- 1 | // Tutorial: https://codeforces.com/blog/entry/43230 2 | // Sample problem: https://www.spoj.com/problems/COT2/ 3 | 4 | #include 5 | 6 | using namespace std; 7 | 8 | #define pb push_back 9 | #define eb emplace_back 10 | #define mk make_pair 11 | #define fi first 12 | #define se second 13 | 14 | typedef long long ll; 15 | typedef pair ii; 16 | const int INF = 0x3f3f3f3f; 17 | const double PI = acos(-1.0); 18 | 19 | const int N = 80008, S = 290, Q = 100011, LOG = 21; 20 | int n, m; 21 | 22 | class Tree { 23 | private: 24 | int pai[N][LOG], dist[N]; 25 | int t; 26 | 27 | void build(int u) { 28 | for (int i = 1; i < LOG; i++) { 29 | int _pai = pai[u][i-1]; 30 | pai[u][i] = pai[_pai][i-1]; 31 | } 32 | } 33 | 34 | void init(int u, int p) { 35 | st[u] = t++; 36 | 37 | pai[u][0] = p; 38 | build(u); 39 | 40 | for (int v : g[u]) { 41 | if (v != p) { 42 | dist[v] = dist[u] + 1; 43 | init(v, u); 44 | } 45 | } 46 | 47 | en[u] = t++; 48 | } 49 | 50 | public: 51 | vectorg[N]; 52 | int st[N], en[N]; 53 | int w[N]; 54 | 55 | void build() { 56 | dist[1] = 0; 57 | t = 0; 58 | init(1, 0); 59 | 60 | map id; 61 | for (int i = 1; i <= n; i++) { 62 | if (!id.count(w[i])) { 63 | id[w[i]] = id.size(); 64 | } 65 | w[i] = id[w[i]]; 66 | } 67 | } 68 | 69 | void add(int u, int v) { 70 | g[u].pb(v); 71 | g[v].pb(u); 72 | } 73 | 74 | int lca(int u, int v){ 75 | if (dist[v] < dist[u]) 76 | swap(v,u); 77 | 78 | int x = dist[v] - dist[u]; 79 | 80 | for (int i = 0; i < LOG; i++) 81 | if (x & (1<= 0; i--) 87 | if (pai[u][i] != pai[v][i]) { 88 | u = pai[u][i]; 89 | v = pai[v][i]; 90 | } 91 | 92 | return pai[u][0]; 93 | } 94 | 95 | } t; 96 | 97 | class Query { 98 | public: 99 | int u, v, lca; 100 | int l, r; 101 | int id; 102 | 103 | Query() {} 104 | 105 | void build() { 106 | if (t.st[u] > t.st[v]) { 107 | swap(u, v); 108 | } 109 | lca = t.lca(u, v); 110 | if (lca == u) { 111 | l = t.st[u]; 112 | r = t.st[v]; 113 | } else { 114 | l = t.en[u]; 115 | r = t.st[v]; 116 | } 117 | } 118 | 119 | bool operator < (const Query& other) const { 120 | int i = l/S, j = other.l/S; 121 | if (i != j) { 122 | return i < j; 123 | } 124 | return r < other.r; 125 | } 126 | }; 127 | 128 | class Mo { 129 | public: 130 | vector v; 131 | int res, ans[Q]; 132 | int freq[N], cnt[N]; 133 | int no[N]; 134 | 135 | Mo(int m) { 136 | v = vector(m); 137 | int i = 0; 138 | for (Query &q : v) { 139 | cin >> q.u >> q.v; 140 | q.id = i++; 141 | q.build(); 142 | } 143 | 144 | for (int i = 1; i <= n; i++) { 145 | no[t.st[i]] = i; 146 | no[t.en[i]] = i; 147 | } 148 | } 149 | 150 | void _add(int i) { 151 | int j = t.w[i]; 152 | 153 | if (!cnt[j]) { 154 | res++; 155 | } 156 | cnt[j]++; 157 | } 158 | 159 | void _remove(int i) { 160 | int j = t.w[i]; 161 | 162 | cnt[j]--; 163 | if (!cnt[j]) { 164 | res--; 165 | } 166 | } 167 | 168 | void add(int id) { 169 | if (id < 0) return; 170 | 171 | int i = no[id]; 172 | 173 | freq[i]++; 174 | if (freq[i] == 1) { 175 | _add(i); 176 | } else { 177 | _remove(i); 178 | } 179 | } 180 | 181 | void remove(int id) { 182 | if (id < 0) return; 183 | 184 | int i = no[id]; 185 | 186 | freq[i]--; 187 | if (freq[i] == 1) { 188 | _add(i); 189 | } else { 190 | _remove(i); 191 | } 192 | } 193 | 194 | void solve() { 195 | sort(v.begin(), v.end()); 196 | res = 0; 197 | 198 | int l = -1, r = -1; 199 | for (const Query& q : v) { 200 | while(r < q.r) { 201 | r++; 202 | add(r); 203 | } 204 | while(l < q.l) { 205 | remove(l); 206 | l++; 207 | } 208 | 209 | while(l > q.l) { 210 | l--; 211 | add(l); 212 | } 213 | while(r > q.r) { 214 | remove(r); 215 | r--; 216 | } 217 | 218 | if (q.lca != q.u) { 219 | int l = t.st[q.lca]; 220 | add(l); 221 | ans[q.id] = res; 222 | remove(l); 223 | } else { 224 | ans[q.id] = res; 225 | } 226 | } 227 | } 228 | 229 | void print() { 230 | for (int i = 0; i < m; i++) { 231 | cout << ans[i] << endl; 232 | } 233 | } 234 | 235 | }; 236 | 237 | int main (void) { 238 | ios_base::sync_with_stdio(false); 239 | 240 | cin >> n >> m; 241 | for (int i = 1; i <= n; i++) { 242 | cin >> t.w[i]; 243 | } 244 | for (int i = 0; i < n-1; i++) { 245 | int u, v; cin >> u >> v; 246 | t.add(u, v); 247 | } 248 | t.build(); 249 | 250 | Mo mo(m); 251 | mo.solve(); 252 | mo.print(); 253 | 254 | return 0; 255 | } 256 | 257 | -------------------------------------------------------------------------------- /trick/sub_super_masks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define mk make_pair 7 | #define fi first 8 | #define se second 9 | 10 | typedef long long ll; 11 | typedef pair ii; 12 | const int INF = 0x3f3f3f3f; 13 | const double PI = acos(-1.0); 14 | 15 | int bits = 20; 16 | 17 | vector submasks (int mask) { 18 | vector subs; 19 | 20 | for (int x = mask; x; x = (x-1)&mask) 21 | subs.pb(x); 22 | subs.pb(0); 23 | 24 | return subs; 25 | } 26 | 27 | vector supermasks (int mask) { 28 | vector supers; 29 | 30 | int msk = ((1LL< supermasks2 (int mask) { 39 | vector supers; 40 | 41 | int msk = ((1LL<