├── APIO 2016 - Boats.cpp ├── APIO 2016 - Fireworks.cpp ├── APIO 2016 - Gap.cpp ├── Battle of Brains 2019 - Parle Treat.cpp ├── CEOI 2004 - Two Sawmills.cpp ├── CodeChef - Big Queries.cpp ├── CodeChef - Power Sums.cpp ├── Codeforces - Bear and Bowling 4.cpp ├── Codeforces - Blood Cousins Return.cpp ├── Codeforces - Blood Cousins.cpp ├── Codeforces - Function.cpp ├── Codeforces - Little Pony and Harmony Chest.cpp ├── Codeforces - Lomsat Gelral.cpp ├── Codeforces - Number of Ways.cpp ├── Codeforces - Product Sum.cpp ├── Codeforces - Tree Requests.cpp ├── Codeforces - Tree-String Problem.cpp ├── Codeforces - Water Tree.cpp ├── Codeforces - Xenia and Bit Operation.cpp ├── HackerEarth - Relatives.cpp ├── HackerEarth - The Grass Type.cpp ├── IOI 2013 - Dreaming.cpp ├── IOI 2014 - Wall.cpp ├── IOI 2015 - Boxes with souvenirs.cpp ├── IOI 2015 - Horses.cpp ├── IOI 2016 - Detecting Molecules.cpp ├── IOI 2016 - Paint By Numbers.cpp ├── IOI 2016 - Roller Coaster Railroad.cpp ├── IOI 2016 - Unscrambling a Messy Bug.cpp ├── LightOJ 1002.cpp ├── LightOJ 1035.cpp ├── LightOJ 1062.cpp ├── LightOJ 1065.cpp ├── LightOJ 1093.cpp ├── LightOJ 1098.cpp ├── LightOJ 1186.cpp ├── LightOJ 1192.cpp ├── LightOJ 1234.cpp ├── LightOJ 1247.cpp ├── LightOJ 1253.cpp ├── LightOJ 1259.cpp ├── LightOJ 1307.cpp ├── LightOJ 1392.cpp ├── NCPC 2015 - Farey Sequence.cpp ├── NCPC 2015 - Palindromic Bases.cpp ├── NCPC 2015 - Train Station.cpp ├── README.md ├── RUET IUPC 2019 - Balloon Heads.cpp ├── SGU 507.cpp ├── SPOJ - Can you answer these queries I.cpp ├── SPOJ - Can you answer these queries III.cpp ├── SPOJ - Can you answer these queries IV.cpp ├── SPOJ - Can you answer these queries V.cpp ├── SPOJ - Cost.cpp ├── SPOJ - Count on a tree II.cpp ├── SPOJ - DQUERY - O((n + q) sqrt(q) + q lg q).cpp ├── SPOJ - DQUERY - O(n + q lg n).cpp ├── SPOJ - Inversion Count.cpp ├── SPOJ - K-Query II.cpp ├── SPOJ - K-Query Online - O(q lg(n) lg(n)).cpp ├── SPOJ - K-Query Online - O(q sqrt(n) lg(n)).cpp ├── SPOJ - K-Query.cpp ├── SPOJ - Leaves.cpp ├── SPOJ - Light Switching.cpp ├── SPOJ - Multiples of 3.cpp ├── SPOJ - Query on a tree.cpp ├── SPOJ - Seinfeld.cpp ├── TopCoder - BipartiteConstruction.cpp ├── TopCoder - DarkMatterParticles.cpp ├── Toph - Act of Random Kindness.cpp ├── USACO - Agri-Net.cpp ├── USACO - Contact.cpp ├── USACO - Cow Pedigrees.cpp ├── USACO - Cow Tours.cpp ├── USACO - Factorials.cpp ├── USACO - Home on the Range.cpp ├── USACO - Humble Numbers.cpp ├── USACO - Longest Prefix.cpp ├── USACO - Money Systems.cpp ├── USACO - Overfencing.cpp ├── USACO - Riding The Fences.cpp ├── USACO - Score Inflation.cpp ├── USACO - Shopping Offers.cpp ├── USACO - The Tamworth Two.cpp ├── UVa 11492.cpp └── UVa 11990.cpp /APIO 2016 - Boats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | APIO 2016 - Boats 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Clustering, Optimization 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef pair pii; 21 | 22 | const int N = 505; 23 | const int M = 1005; 24 | const int MOD = 1e9 + 7; 25 | 26 | vector v; 27 | vector z[M]; 28 | 29 | int x[M], y[M]; 30 | int n, m, a[N], b[N]; 31 | 32 | long long dp[N][M]; 33 | int sz[M], wide[M]; 34 | 35 | int counter = 1; 36 | int comb[M][N], inverse[N]; 37 | 38 | int bigMod (int a, int e) { 39 | if (e == -1) e = MOD - 2; 40 | int r = 1; while (e) { 41 | if (e & 1) r = (r * 1ll * a) % MOD; 42 | a = (a * 1ll * a) % MOD; 43 | e >>= 1; 44 | } 45 | return r; 46 | } 47 | 48 | int nCr (int n, int r) { 49 | if (n < r) return 0; 50 | long long res = 1ll; 51 | for (int i = n, j = 1; j <= r; --i, ++j) { 52 | res *= 1ll * i, res %= MOD; 53 | res *= inverse[j], res %= MOD; 54 | } 55 | return res; 56 | } 57 | 58 | int main (int argc, char const *argv[]) { 59 | scanf("%d", &n); 60 | for (int i = 1; i <= n; ++i) { 61 | scanf("%d %d", a + i, b + i); 62 | v.push_back({a[i], 0}); 63 | v.push_back({b[i], 1}); 64 | } 65 | sort(v.begin(), v.end()); 66 | 67 | for (int i = 1; i < n + n; ++i) { 68 | int one = v[i - 1].second, two = v[i].second; 69 | int l = v[i - 1].first, r = v[i].first; 70 | 71 | if (!one and !two) { 72 | --r, ++counter; 73 | if (l <= r) x[++m] = l, y[m] = r; 74 | } else if (!one and two) { 75 | --counter; 76 | if (l <= r) x[++m] = l, y[m] = r; 77 | } else if (one and two) { 78 | ++l, --counter; 79 | if (l <= r) x[++m] = l, y[m] = r; 80 | } else { 81 | ++l, --r; 82 | if (counter and l <= r) x[++m] = l, y[m] = r; 83 | ++counter; 84 | } 85 | } 86 | 87 | for (int i = 1; i <= m; ++i) { 88 | for (int j = 1; j <= n; ++j) { 89 | if (a[j] <= x[i] and y[i] <= b[j]) { 90 | z[i].push_back(j); 91 | ++sz[i]; 92 | } 93 | } 94 | wide[i] = y[i] - x[i] + 1; 95 | } 96 | 97 | for (int i = 1; i < N; ++i) { 98 | inverse[i] = bigMod(i, -1); 99 | } 100 | for (int i = 1; i <= m; ++i) { 101 | for (int j = 0; j <= sz[i]; ++j) { 102 | comb[i][j] = nCr(wide[i] + j, j + 1); 103 | } 104 | } 105 | 106 | for (int i = 0; i <= n + 1; ++i) { 107 | dp[i][m + 1] = 1; 108 | } 109 | for (int i = 0; i <= m + 1; ++i) { 110 | dp[n + 1][i] = 1; 111 | } 112 | for (int at = n; at; --at) { 113 | for (int range = m; range; --range) { 114 | dp[at][range] = dp[at][range + 1]; 115 | int start = 0; 116 | while (start < sz[range] and z[range][start] < at) ++start; 117 | for (int i = start; i < sz[range]; ++i) { 118 | dp[at][range] += comb[range][i - start] * dp[z[range][i] + 1][range + 1]; 119 | dp[at][range] %= MOD; 120 | } 121 | } 122 | } 123 | 124 | dp[1][1] += MOD - 1, dp[1][1] %= MOD; 125 | printf("%lld\n", dp[1][1]); 126 | return 0; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /APIO 2016 - Fireworks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | const int N = 300010; 8 | 9 | int n, m, p[N]; 10 | vector g[N]; 11 | ll w[N], a[N], b[N]; 12 | priority_queue *pq[N]; 13 | 14 | int main() { 15 | cin >> m >> n; n += m; 16 | for (int i = 2; i <= n; ++i) { 17 | scanf("%d %lld", p + i, w + i); 18 | g[p[i]].emplace_back(i); 19 | } 20 | for (int i = m + 1; i <= n; ++i) { 21 | a[i] = 1, b[i] = -w[i]; 22 | pq[i] = new priority_queue (); 23 | pq[i] -> emplace(w[i]); pq[i] -> emplace(w[i]); 24 | } 25 | for (int i = m; i >= 1; --i) { 26 | pq[i] = new priority_queue (); 27 | for (int j : g[i]) { 28 | if (pq[j] -> size() > pq[i] -> size()) swap(pq[i], pq[j]); 29 | while (!(pq[j] -> empty())) pq[i] -> emplace(pq[j] -> top()), pq[j] -> pop(); 30 | a[i] += a[j], b[i] += b[j]; 31 | } 32 | while (a[i] > 1) b[i] += pq[i] -> top(), --a[i], pq[i] -> pop(); b[i] -= w[i]; 33 | ll one = pq[i] -> top(); pq[i] -> pop(); 34 | ll zero = pq[i] -> top(); pq[i] -> pop(); 35 | pq[i] -> emplace(one + w[i]); pq[i] -> emplace(zero + w[i]); 36 | } 37 | cout << a[1] * pq[1] -> top() + b[1] << '\n'; 38 | return 0; 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /APIO 2016 - Gap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | APIO 2016 - Gap 9 | 10 | Category: Ad hoc 11 | 12 | Keys: Constructive Algorithm, Pigeonhole Principle 13 | 14 | */ 15 | 16 | #include 17 | #include "gap.h" 18 | 19 | using namespace std; 20 | 21 | typedef long long ll; 22 | 23 | ll findGap (int subTask, int n) { 24 | ll l, r, ret = 0; 25 | MinMax(0, 1e18, &l, &r); 26 | if (subTask == 1) { 27 | for (int done = 2; done < n; done += 2) { 28 | ll new_l, new_r; 29 | MinMax(l + 1, r - 1, &new_l, &new_r); 30 | if (new_l == -1) break; 31 | ret = max(ret, new_l - l); 32 | ret = max(ret, r - new_r); 33 | l = new_l, r = new_r; 34 | } 35 | } else { 36 | ll block = (r - l + n - 3)/(n - 1); 37 | for (ll i = l + 1, j = i + block; i < r; i += block, j += block) { 38 | ll new_l, new_r; 39 | if (j > r) j = r; 40 | MinMax(i, j - 1, &new_l, &new_r); 41 | if (new_l != -1) { 42 | ret = max(ret, new_l - l); 43 | l = new_r; 44 | } 45 | } 46 | } 47 | ret = max(ret, r - l); 48 | return ret; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Battle of Brains 2019 - Parle Treat.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | const int MOD = 1e9 + 7; 8 | 9 | // sum [(x + kn) / m] for 0 <= k < m 10 | inline ll aux (ll x, ll n, ll m) { 11 | ll g = __gcd(n, m); 12 | return g * (x / g) + (m * n - m - n + g) / 2; 13 | } 14 | 15 | // sum [(x + kn) / m] for 0 <= k < lim < m 16 | ll get (ll x, ll n, ll m, ll lim) { 17 | if (!lim) return 0; 18 | ll ret = lim * (x / m) + lim * (lim - 1) * (n / m) / 2; 19 | n %= m, x %= m; if (!n) return ret; 20 | ll p = (x + (lim - 1) * n) / m; 21 | return ret + p * lim - get(m - x + n - 1, m, n, p); 22 | } 23 | 24 | // sum [(x + kn) / m] for 0 <= k < lim in O(lg max(n, m)) 25 | // m > 0, lim >= 0 26 | inline ll floorAPsum (ll x, ll n, ll m, ll lim) { 27 | ll ret = 0; 28 | if (x < 0) { 29 | ll q = x / m; x %= m; 30 | if (x) x += m, --q; 31 | ret += q * lim; 32 | } if (n < 0) { 33 | ll q = n / m; n %= m; 34 | if (n) n += m, --q; 35 | ret += lim * (lim - 1) * q / 2; 36 | } 37 | ll tmp = aux(x, n, m), tot = lim / m; 38 | ret += tmp * tot + tot * (tot - 1) * n * m / 2 + tot * n * (lim - tot * m); 39 | return ret + get(x, n, m, lim % m); 40 | } 41 | 42 | inline ll floor (ll x, ll y) { 43 | if (x % y == 0) return x / y; 44 | return x > 0 ? x / y : x / y - 1; 45 | } 46 | 47 | inline ll ceiling (ll x, ll y) { 48 | if (x % y == 0) return x / y; 49 | return x > 0 ? x / y + 1 : x / y; 50 | } 51 | 52 | // find x, y such that ax + by = gcd(a, b) 53 | ll extEuclidean (ll a, ll b, ll &x, ll &y) { 54 | ll _x = y = 0, _y = x = 1; 55 | while (b) { 56 | ll q = a / b, t = b; 57 | b = a % b, a = t; 58 | t = _x; _x = x - q * _x; x = t; 59 | t = _y; _y = y - q * _y; y = t; 60 | } 61 | return a; 62 | } 63 | 64 | ll a, b, c, d, e, x[2], y[2], z[2]; 65 | 66 | int main() { 67 | cin >> a >> b >> c >> d >> e; 68 | cin >> x[0] >> x[1] >> y[0] >> y[1] >> z[0] >> z[1]; 69 | ll ans = 0; 70 | for (ll it = z[0]; it <= z[1]; ++it) { 71 | ll f = e - c * it, g = __gcd(b, d), X, Y, Z, W; 72 | // f = aX + bY + dW = aX + gZ 73 | ll h = extEuclidean(a, g, X, Z); 74 | if (f % h) continue; X *= f / h, Z *= f / h; 75 | // general solution: {X + k * g / h, Z - k * a / h} 76 | ll lt = ceiling(x[0] - X, g / h), rt = floor(x[1] - X, g / h); 77 | swap(lt, rt); lt = -lt, rt = -rt; rt -= lt; 78 | // st, st + jump, ..., st + rt * jump 79 | ll jump = a / h, st = Z + lt * jump; 80 | extEuclidean(b, d, Y, W); 81 | ans = (ans + floorAPsum(y[1] - Y * st + (d / g), -Y * jump, d / g, rt + 1)) % MOD; 82 | ans = (ans - floorAPsum(y[0] - Y * st + (d / g) - 1, -Y * jump, d / g, rt + 1)) % MOD; 83 | } 84 | ans += MOD, ans %= MOD; cout << ans << '\n'; 85 | return 0; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /CEOI 2004 - Two Sawmills.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Central European Olympiad in Informatics 2004 - Two Sawmills 9 | 10 | Category: Data Structures 11 | 12 | Keys: Algebraic Manipulation, Convex Hull Trick 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 2e4 + 10; 21 | 22 | int n; 23 | long long a[N]; 24 | long long total; 25 | long long w[N], d[N]; 26 | vector m; 27 | vector c; 28 | int size, pointer; 29 | 30 | bool bad (int l1, int l2, int l3) { 31 | return (c[l2] - c[l1]) * (m[l1] - m[l3]) >= (c[l3] - c[l1]) * (m[l1] - m[l2]); 32 | } 33 | 34 | void add (long long m0, long long c0) { 35 | ++size; 36 | m.push_back(m0); 37 | c.push_back(c0); 38 | while (size >= 3 and bad(size - 3, size - 2, size - 1)) { 39 | --size; 40 | m.erase(m.end() - 2); 41 | c.erase(c.end() - 2); 42 | } 43 | } 44 | 45 | long long query (long long x) { 46 | if (pointer >= size) pointer = size - 1; 47 | while (pointer < size - 1 and m[pointer] * x + c[pointer] < m[pointer + 1] * x + c[pointer + 1]) { 48 | ++pointer; 49 | } 50 | return m[pointer] * x + c[pointer]; 51 | } 52 | 53 | int main (int argc, char const *argv[]) { 54 | scanf("%d", &n); 55 | for (int i = 1; i <= n; ++i) { 56 | scanf("%lld %lld", w + i, d + i + 1); 57 | total -= w[i] * d[i]; 58 | w[i] += w[i - 1], d[i + 1] += d[i]; 59 | } 60 | total += d[n + 1] * w[n]; 61 | add(w[1], 0); 62 | long long ans = 0LL; 63 | for (int i = 2; i <= n; ++i) { 64 | ans = max(ans, query(d[i]) + w[i] * (d[n + 1] - d[i])); 65 | add(w[i], -w[i] * d[i]); 66 | } 67 | printf("%lld\n", total - ans); 68 | return 0; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /CodeChef - Big Queries.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | CodeChef - Big Queries (BGQRS) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree, Lazy Propagation, Preprocessing 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e5 + 10; 21 | 22 | struct node { 23 | int two, five, l, r, lazy2, lazy5; 24 | node () {two = five = l = r = lazy2 = lazy5 = 0;} 25 | }; 26 | 27 | node tree[3 * N]; 28 | int t, n, m, a[N], leg2[N], leg5[N]; 29 | 30 | int expo (int x, int p) { 31 | int tot = 0; 32 | while (x % p == 0) ++tot, x /= p; 33 | return tot; 34 | } 35 | 36 | int legendre (int x, int p) { 37 | int tot = 0, power = p; 38 | while (x >= power) tot += x/power, power *= p; 39 | return tot; 40 | } 41 | 42 | node merge (node a, node b) { 43 | node c; 44 | c.two = a.two + b.two; 45 | c.five = a.five + b.five; 46 | return c; 47 | } 48 | 49 | void build (int u, int b, int e) { 50 | if (b == e) { 51 | tree[u].two = expo(a[b], 2); 52 | tree[u].five = expo(a[b], 5); 53 | return; 54 | } 55 | 56 | int l = u << 1, r = l | 1, m = b + e >> 1; 57 | build(l, b, m), build(r, m + 1, e); 58 | tree[u] = merge(tree[l], tree[r]); 59 | } 60 | 61 | void propagate (int u, int b, int e) { 62 | int l = tree[u].l, r = tree[u].r; 63 | 64 | if (l + r) { 65 | tree[u].two = leg2[r] - leg2[l - 1]; 66 | tree[u].five = leg5[r] - leg5[l - 1]; 67 | } 68 | 69 | tree[u].two += tree[u].lazy2 * (e - b + 1); 70 | tree[u].five += tree[u].lazy5 * (e - b + 1); 71 | 72 | if (b != e) { 73 | int lchild = u << 1, rchild = lchild | 1; 74 | 75 | if (l + r) { 76 | tree[lchild].l = l, tree[lchild].r = l + r >> 1; 77 | tree[rchild].l = 1 + (l + r >> 1), tree[rchild].r = r; 78 | tree[lchild].lazy2 = tree[lchild].lazy5 = 0; 79 | tree[rchild].lazy2 = tree[rchild].lazy5 = 0; 80 | } 81 | 82 | tree[lchild].lazy2 += tree[u].lazy2; 83 | tree[rchild].lazy2 += tree[u].lazy2; 84 | tree[lchild].lazy5 += tree[u].lazy5; 85 | tree[rchild].lazy5 += tree[u].lazy5; 86 | } 87 | 88 | tree[u].l = tree[u].r = tree[u].lazy2 = tree[u].lazy5 = 0; 89 | } 90 | 91 | void update1 (int u, int b, int e, int p, int q, int x, int y) { 92 | if (tree[u].l + tree[u].r + tree[u].lazy2 + tree[u].lazy5) propagate(u, b, e); 93 | if (b > q or e < p) return; 94 | if (b >= p and e <= q) { 95 | tree[u].lazy2 += x, tree[u].lazy5 += y; 96 | propagate(u, b, e); 97 | return; 98 | } 99 | 100 | int l = u << 1, r = l | 1, m = b + e >> 1; 101 | update1(l, b, m, p, q, x, y); 102 | update1(r, m + 1, e, p, q, x, y); 103 | tree[u] = merge(tree[l], tree[r]); 104 | } 105 | 106 | void update2 (int u, int b, int e, int p, int q) { 107 | if (tree[u].l + tree[u].r + tree[u].lazy2 + tree[u].lazy5) propagate(u, b, e); 108 | if (b > q or e < p) return; 109 | if (b >= p and e <= q) { 110 | tree[u].lazy2 = tree[u].lazy5 = 0; 111 | tree[u].l = b - p + 1, tree[u].r = e - p + 1; 112 | propagate(u, b, e); 113 | return; 114 | } 115 | 116 | int l = u << 1, r = l | 1, m = b + e >> 1; 117 | update2(l, b, m, p, q), update2(r, m + 1, e, p, q); 118 | tree[u] = merge(tree[l], tree[r]); 119 | } 120 | 121 | pair query (int u, int b, int e, int p, int q) { 122 | if (b > q or e < p) return {0, 0}; 123 | if (tree[u].l + tree[u].r + tree[u].lazy2 + tree[u].lazy5) propagate(u, b, e); 124 | if (b >= p and e <= q) return {tree[u].two, tree[u].five}; 125 | 126 | int l = u << 1, r = l | 1, m = b + e >> 1; 127 | pair lchild = query(l, b, m, p, q); 128 | pair rchild = query(r, m + 1, e, p, q); 129 | 130 | return {lchild.first + rchild.first, lchild.second + rchild.second}; 131 | } 132 | 133 | int main (int argc, char const *argv[]) { 134 | for (int i = 1; i < N; ++i) 135 | leg2[i] = legendre(i, 2), leg5[i] = legendre(i, 5); 136 | 137 | scanf("%d", &t); while (t--) { 138 | scanf("%d %d", &n, &m); 139 | for (int i = 1; i <= n; ++i) scanf("%d", a + i); 140 | build(1, 1, n); 141 | 142 | long long sum = 0; 143 | 144 | while (m--) { 145 | int cmd, l, r; 146 | scanf("%d %d %d", &cmd, &l, &r); 147 | 148 | if (cmd == 1) { 149 | int x; scanf("%d", &x); 150 | update1(1, 1, n, l, r, expo(x, 2), expo(x, 5)); 151 | } else if (cmd == 2) { 152 | int x; scanf("%d", &x); 153 | update2(1, 1, n, l, r); 154 | update1(1, 1, n, l, r, expo(x, 2), expo(x, 5)); 155 | } else { 156 | pair res = query(1, 1, n, l, r); 157 | sum += (long long) min(res.first, res.second); 158 | } 159 | } 160 | 161 | printf("%lld\n", sum); 162 | memset(tree, 0, sizeof tree); 163 | } 164 | return 0; 165 | } 166 | 167 | -------------------------------------------------------------------------------- /CodeChef - Power Sums.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | CodeChef - Power Sums (POWSUMS) 9 | 10 | Category: Mathematics 11 | 12 | Keys: Newton's Sums, Cantor-Zassenhaus Algorithm 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 605; 21 | const int MOD = 1e9 + 7; 22 | 23 | struct polynomial { 24 | int deg; 25 | long long coeff[N]; 26 | 27 | polynomial () { 28 | deg = 0; 29 | memset(coeff, 0, sizeof coeff); 30 | } 31 | }; 32 | 33 | int t, n, q; 34 | long long p[N]; 35 | polynomial f, g, h; 36 | vector roots; 37 | 38 | long long bigMod (long long a, long long e) { 39 | if (e == -1) e = MOD - 2; 40 | e %= (MOD - 1); 41 | long long r = 1; 42 | while (e) { 43 | if (e & 1) r = (r * a) % MOD; 44 | a = (a * a) % MOD; 45 | e >>= 1; 46 | } 47 | return r; 48 | } 49 | 50 | polynomial product (polynomial f, polynomial g) { 51 | polynomial h; 52 | h.deg = f.deg + g.deg; 53 | 54 | for (int i = 0; i <= f.deg; ++i) 55 | for (int j = 0; j <= g.deg; ++j) 56 | h.coeff[i + j] += f.coeff[i] * g.coeff[j], h.coeff[i + j] %= MOD; 57 | 58 | return h; 59 | } 60 | 61 | // Assuming deg f >= deg g 62 | polynomial quotient (polynomial f, polynomial g) { 63 | polynomial q; 64 | q.deg = f.deg - g.deg; 65 | 66 | for (int i = q.deg; i >= 0; --i) { 67 | q.coeff[i] = (f.coeff[g.deg + i] * bigMod(g.coeff[g.deg], -1)) % MOD; 68 | for (int j = g.deg; j >= 0; --j) 69 | f.coeff[i + j] -= q.coeff[i] * g.coeff[j], f.coeff[i + j] %= MOD; 70 | } 71 | 72 | return q; 73 | } 74 | 75 | polynomial remainder (polynomial f, polynomial g) { 76 | if (f.deg < g.deg) return f; 77 | 78 | for (int i = f.deg - g.deg; i >= 0; --i) { 79 | long long c = (f.coeff[g.deg + i] * bigMod(g.coeff[g.deg], -1)) % MOD; 80 | for (int j = g.deg; j >= 0; --j) 81 | f.coeff[i + j] -= c * g.coeff[j], f.coeff[i + j] %= MOD; 82 | } 83 | 84 | f.deg = max(0, g.deg - 1); 85 | while (f.deg > 0 and f.coeff[f.deg] == 0) --f.deg; 86 | return f; 87 | } 88 | 89 | // Euclidean Algorithm 90 | polynomial gcd (polynomial f, polynomial g) { 91 | if (g.deg == 0 and g.coeff[0] == 0) return f; 92 | return gcd(g, remainder(f, g)); 93 | } 94 | 95 | // Cantor-Zassenhaus Algorithm 96 | void findRoots (polynomial f) { 97 | if (f.deg == 1) { 98 | long long root = (-1 * f.coeff[0] * bigMod(f.coeff[1], -1)) % MOD; 99 | if (root < 0) root += MOD; 100 | roots.push_back(root); 101 | return; 102 | } 103 | 104 | while (true) { 105 | long long d = rand() % MOD; 106 | polynomial a, r; 107 | a.deg = 1, a.coeff[1] = 1, a.coeff[0] = d, r.coeff[0] = 1; 108 | int expo = (MOD - 1) >> 1; 109 | 110 | while (expo) { 111 | if (expo & 1) r = remainder(product(r, a), f); 112 | a = remainder(product(a, a), f); 113 | expo >>= 1; 114 | } 115 | 116 | --r.coeff[0]; 117 | a = gcd(f, r); 118 | 119 | if (a.deg > 0 and a.deg < f.deg) { 120 | r = quotient(f, a); 121 | findRoots(a), findRoots(r); 122 | return; 123 | } 124 | } 125 | } 126 | 127 | int main (int argc, char const *argv[]) { 128 | scanf("%d", &t); 129 | for (int z = 1; z <= t; ++z) { 130 | scanf("%d %d", &n, &q); 131 | for (int i = 1; i <= n; ++i) scanf("%lld", p + i); 132 | 133 | // Algebraic manipulations for first subtask 134 | if (t > 1) { 135 | if (n == 3) { 136 | long long abbcca = (((p[1] * p[1] - p[2]) % MOD) * bigMod(2, -1)) % MOD; 137 | long long abc = (((p[3] - p[1] * (p[2] - abbcca)) % MOD) * bigMod(3, -1)) % MOD; 138 | p[4] = (p[1] * p[3] + abc * p[1] - p[2] * abbcca) % MOD; 139 | } else if (n == 2) { 140 | long long ab = (((p[1] * p[1] - p[2]) % MOD) * bigMod(2, -1)) % MOD; 141 | p[3] = (p[1] * (p[2] - ab)) % MOD; 142 | p[4] = (p[2] * p[2] - 2 * ab * ab) % MOD; 143 | } else if (n == 1) { 144 | p[2] = (p[1] * p[1]) % MOD; 145 | p[3] = (p[2] * p[1]) % MOD; 146 | p[4] = (p[3] * p[1]) % MOD; 147 | } 148 | 149 | while (q--) { 150 | long long x; 151 | scanf("%lld", &x); 152 | printf("%lld ", (p[x] + MOD) % MOD); 153 | } 154 | 155 | puts(""); 156 | continue; 157 | } 158 | 159 | f.deg = n, f.coeff[n] = 1; 160 | 161 | // Extraction of polynomial from Newton's identities 162 | for (int i = n - 1; i >= 0; --i) { 163 | f.coeff[i] = 0; 164 | for (int j = n, k = n - i; k; --j, --k) { 165 | f.coeff[i] -= p[k] * f.coeff[j]; 166 | f.coeff[i] %= MOD; 167 | } 168 | f.coeff[i] *= bigMod(n - i, - 1), f.coeff[i] %= MOD; 169 | } 170 | 171 | // Extraction of 0 roots 172 | int pos = 0; 173 | while (f.coeff[pos] == 0) ++pos, roots.push_back(0); 174 | for (int i = pos; i <= f.deg; ++i) f.coeff[i - pos] = f.coeff[i]; 175 | f.deg -= pos; 176 | 177 | findRoots(f); 178 | 179 | while (q--) { 180 | long long x, res = 0; 181 | scanf("%lld", &x); 182 | for (int i = 0; i < n; ++i) res += bigMod(roots[i], x), res %= MOD; 183 | printf("%lld ", (res + MOD) % MOD); 184 | } 185 | 186 | puts(""); 187 | } 188 | return 0; 189 | } 190 | 191 | -------------------------------------------------------------------------------- /Codeforces - Bear and Bowling 4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 660F - Bear and Bowling 4 9 | 10 | Category: Data Structures 11 | 12 | Keys: Convex Hull Trick 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 2e5 + 10; 21 | 22 | int n; 23 | long long sum[N]; 24 | long long wsum[N]; 25 | long long val[N]; 26 | vector m; 27 | vector c; 28 | int size = 0; 29 | 30 | bool bad (int l1, int l2, int l3) { 31 | return (c[l1] - c[l2]) * (m[l3] - m[l1]) <= (c[l1] - c[l3]) * (m[l2] - m[l1]); 32 | } 33 | 34 | void add (long long m0, long long c0) { 35 | ++size; 36 | m.push_back(m0); 37 | c.push_back(c0); 38 | while (size >= 3 and bad(size - 3, size - 2, size - 1)) { 39 | --size; 40 | m.erase(m.end() - 2); 41 | c.erase(c.end() - 2); 42 | } 43 | } 44 | 45 | long long query (long long x) { 46 | long long last = m[size - 1] * x + c[size - 1]; 47 | int lo = 0, hi = size - 2; 48 | while (lo < hi) { 49 | int mid = lo + hi >> 1; 50 | long long now = m[mid] * x + c[mid]; 51 | long long after = m[mid + 1] * x + c[mid + 1]; 52 | if (now > after) lo = mid + 1; 53 | else hi = mid; 54 | } 55 | return min(last, m[lo] * x + c[lo]); 56 | } 57 | 58 | int main (int argc, char const *argv[]) { 59 | scanf("%d", &n); 60 | for (int i = 1; i <= n; ++i) { 61 | scanf("%lld", sum + i); 62 | wsum[i] = i * sum[i]; 63 | sum[i] += sum[i - 1]; 64 | wsum[i] += wsum[i - 1]; 65 | val[i] = wsum[i] - i * sum[i]; 66 | } 67 | add(0, 0); 68 | long long ans = 0; 69 | for (int i = 1; i <= n; ++i) { 70 | ans = max(ans, wsum[i] - query(sum[i])); 71 | add(i, val[i]); 72 | } 73 | printf("%lld\n", ans); 74 | return 0; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /Codeforces - Blood Cousins Return.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 246E - Blood Cousins Return 9 | 10 | Category: Graph Theory 11 | 12 | Keys: DSU on Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef pair data; 21 | 22 | #define x first 23 | #define y second 24 | 25 | const int N = 100010; 26 | 27 | string s[N]; 28 | int n, m, h[N]; 29 | vector g[N]; 30 | vector roots; 31 | vector q[N]; 32 | int root, ans[N]; 33 | 34 | void go (int u, int deep = 1) { 35 | h[u] = deep; 36 | for (int v : g[u]) { 37 | go(v, deep + 1); 38 | } 39 | } 40 | 41 | void dfs (int u, map > &f) { 42 | for (int v : g[u]) { 43 | map > t; 44 | dfs(v, t); 45 | if (t.size() > f.size()) { 46 | f.swap(t); 47 | } 48 | for (auto it : t) { 49 | for (string z : it.y) { 50 | f[it.x].insert(z); 51 | } 52 | } 53 | } 54 | f[h[u]].insert(s[u]); 55 | for (data it : q[u]) { 56 | ans[it.y] = f[it.x].size(); 57 | } 58 | } 59 | 60 | int main() { 61 | scanf("%d", &n); 62 | for (int i = 1; i <= n; ++i) { 63 | int par; 64 | cin >> s[i]; 65 | scanf("%d", &par); 66 | if (par) { 67 | g[par].push_back(i); 68 | } else { 69 | roots.push_back(i); 70 | } 71 | } 72 | for (int root : roots) { 73 | go(root); 74 | } 75 | scanf("%d", &m); 76 | for (int i = 1; i <= m; ++i) { 77 | int u, k; 78 | scanf("%d %d", &u, &k); 79 | k += h[u]; 80 | q[u].emplace_back(k, i); 81 | } 82 | for (int root : roots) { 83 | map > f; 84 | dfs(root, f); 85 | } 86 | for (int i = 1; i <= m; ++i) { 87 | printf("%d\n", ans[i]); 88 | } 89 | return 0; 90 | } 91 | 92 | -------------------------------------------------------------------------------- /Codeforces - Blood Cousins.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 208E - Blood Cousins 9 | 10 | Category: Graph Theory 11 | 12 | Keys: DSU on Tree, Binary Jump 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef pair data; 21 | 22 | #define x first 23 | #define y second 24 | 25 | const int LG = 20; 26 | const int N = 100010; 27 | 28 | int par[N][LG]; 29 | int n, m, h[N]; 30 | vector g[N]; 31 | vector roots; 32 | vector q[N]; 33 | int root, ans[N]; 34 | 35 | void go (int u, int deep = 1) { 36 | h[u] = deep; 37 | for (int v : g[u]) { 38 | par[v][0] = u; 39 | go(v, deep + 1); 40 | } 41 | } 42 | 43 | void dfs (int u, map &f) { 44 | for (int v : g[u]) { 45 | map t; 46 | dfs(v, t); 47 | if (t.size() > f.size()) { 48 | f.swap(t); 49 | } 50 | for (auto it : t) { 51 | f[it.x] += it.y; 52 | } 53 | } 54 | ++f[h[u]]; 55 | for (auto it : q[u]) { 56 | ans[it.y] = f[it.x] - 1; 57 | } 58 | } 59 | 60 | int ancestor (int u, int k) { 61 | for (int i = LG - 1; i >= 0; --i) { 62 | if (k >= (1 << i)) { 63 | k -= (1 << i); 64 | u = par[u][i]; 65 | } 66 | } 67 | return u; 68 | } 69 | 70 | int main() { 71 | scanf("%d", &n); 72 | for (int i = 1; i <= n; ++i) { 73 | int par; 74 | scanf("%d", &par); 75 | if (par) { 76 | g[par].push_back(i); 77 | } else { 78 | roots.push_back(i); 79 | } 80 | } 81 | memset(par, -1, sizeof par); 82 | for (int root : roots) { 83 | go(root); 84 | } 85 | for (int i = 1; i < LG; ++i) { 86 | for (int j = 1; j <= n; ++j) { 87 | if (par[j][i - 1] != -1) { 88 | par[j][i] = par[par[j][i - 1]][i - 1]; 89 | } 90 | } 91 | } 92 | scanf("%d", &m); 93 | for (int i = 1; i <= m; ++i) { 94 | int u, k; 95 | scanf("%d %d", &u, &k); 96 | if (h[u] <= k) { 97 | continue; 98 | } 99 | int v = ancestor(u, k); 100 | q[v].emplace_back(h[u], i); 101 | } 102 | for (int root : roots) { 103 | map f; 104 | dfs(root, f); 105 | } 106 | for (int i = 1; i <= m; ++i) { 107 | printf("%d ", ans[i]); 108 | } 109 | puts(""); 110 | return 0; 111 | } 112 | 113 | -------------------------------------------------------------------------------- /Codeforces - Function.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 455E - Function 9 | 10 | Category: Data Structures 11 | 12 | Keys: Observation, Merge Sort Tree, Segment Tree, Convex Hull Trick 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e5 + 10; 21 | const long long INF = 1e16 + 10; 22 | 23 | struct line { 24 | long long m, c; 25 | line () {} 26 | line (long long _m, long long _c) { 27 | m = _m, c = _c; 28 | } 29 | long long at (long long x) { 30 | return m * x + c; 31 | } 32 | bool operator < (const line &l) const { 33 | return m < l.m; 34 | } 35 | }; 36 | 37 | int n, m; 38 | long long a[N]; 39 | long long sum[N]; 40 | vector mst[4 * N]; // Merge Sort Tree 41 | vector tree[4 * N]; // Segment Tree 42 | 43 | bool bad (line l1, line l2, line l3) { 44 | return (l1.c - l2.c) * (l3.m - l1.m) >= (l1.c - l3.c) * (l2.m - l1.m); 45 | } 46 | 47 | void add (vector &v, line l) { 48 | v.push_back(l); 49 | int size = v.size(); 50 | while (size >= 3 and bad(v[size - 3], v[size - 2], v[size - 1])) { 51 | --size; 52 | v.erase(v.end() - 2); 53 | } 54 | } 55 | 56 | void init (int u, int b, int e) { 57 | if (b == e) { 58 | mst[u].push_back(line(a[b], sum[b] - b * a[b])); 59 | tree[u].push_back(line(a[b], sum[b] - b * a[b])); 60 | return; 61 | } 62 | int l = u << 1, r = l | 1, m = b + e >> 1; 63 | init(l, b, m), init(r, m + 1, e); 64 | merge(mst[l].begin(), mst[l].end(), mst[r].begin(), mst[r].end(), back_inserter(mst[u])); 65 | for (unsigned i = 0; i < mst[u].size(); ++i) { 66 | add(tree[u], mst[u][i]); 67 | } 68 | } 69 | 70 | long long query (vector &v, long long x) { 71 | int size = v.size(); 72 | int lo = 0, hi = size - 2; 73 | while (lo < hi) { 74 | int mid = lo + hi >> 1; 75 | if (v[mid].at(x) < v[mid + 1].at(x)) { 76 | lo = mid + 1; 77 | } else { 78 | hi = mid; 79 | } 80 | } 81 | return v[lo].at(x); 82 | } 83 | 84 | long long query (int u, int b, int e, int p, int q, long long x) { 85 | if (b > q or e < p) return -INF; 86 | if (b >= p and e <= q) return query(tree[u], x); 87 | int l = u << 1, r = l | 1, m = b + e >> 1; 88 | long long left = query(l, b, m, p, q, x); 89 | long long right = query(r, m + 1, e, p, q, x); 90 | return max(left, right); 91 | } 92 | 93 | int main (int argc, char const *argv[]) { 94 | scanf("%d", &n); 95 | for (int i = 1; i <= n; ++i) { 96 | scanf("%lld", a + i); 97 | sum[i] = sum[i - 1] + a[i]; 98 | } 99 | init(1, 1, n); 100 | scanf("%d", &m); while (m--) { 101 | int x, y; 102 | scanf("%d %d", &x, &y); 103 | long long offset = query(1, 1, n, y - x + 1, y, y - x); 104 | printf("%lld\n", sum[y] - offset); 105 | } 106 | return 0; 107 | } 108 | 109 | -------------------------------------------------------------------------------- /Codeforces - Little Pony and Harmony Chest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 453B - Little Pony and Harmony Chest 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Bitmasks, Bounding, Optimization 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | struct data { 21 | int x, y, z; 22 | data () {} 23 | data (int _x, int _y, int _z) { 24 | x = _x, y = _y, z = _z; 25 | } 26 | }; 27 | 28 | const int N = 105; 29 | const int LIM = 60; 30 | const int INF = 1e9 + 5; 31 | const int MASK = (1 << 17) + 5; 32 | 33 | vector p; 34 | data state[N][MASK]; 35 | int n, m, a[N]; 36 | int f[N][MASK]; 37 | int mask[N]; 38 | 39 | bool is_prime (int x) { 40 | for (int i = 2; i * i <= x; ++i) { 41 | if (x % i == 0) { 42 | return false; 43 | } 44 | } 45 | return true; 46 | } 47 | 48 | int main() { 49 | scanf("%d", &n); 50 | for (int i = 0; i < n; ++i) { 51 | scanf("%d", a + i); 52 | } 53 | for (int i = 2; i <= LIM; ++i) { 54 | if (is_prime(i)) { 55 | p.push_back(i); 56 | } 57 | } 58 | m = p.size(); 59 | for (int i = 1; i <= LIM; ++i) { 60 | for (int j = 0; j < m; ++j) { 61 | if (i % p[j] == 0) { 62 | mask[i] |= 1 << j; 63 | } 64 | } 65 | } 66 | for (int i = 0; i < n; ++i) { 67 | for (int j = 0; j < 1 << m; ++j) { 68 | f[i][j] = INF; 69 | } 70 | } 71 | for (int i = n - 1; i >= 0; --i) { 72 | for (int j = 0; j < 1 << m; ++j) { 73 | for (int k = 1; k <= LIM; ++k) { 74 | if (j & mask[k]) continue; 75 | int s = j | mask[k]; 76 | int val = abs(a[i] - k) + f[i + 1][s]; 77 | if (val < f[i][j]) { 78 | f[i][j] = val; 79 | state[i][j] = data(i + 1, s, k); 80 | } 81 | } 82 | } 83 | } 84 | int i = 0, j = 0; 85 | for (int k = 0; k < n; ++k) { 86 | printf("%d ", state[i][j].z); 87 | int next_i = state[i][j].x; 88 | int next_j = state[i][j].y; 89 | i = next_i, j = next_j; 90 | } 91 | puts(""); 92 | return 0; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /Codeforces - Lomsat Gelral.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 600E - Lomsat Gelral 9 | 10 | Category: Graph Theory 11 | 12 | Keys: DSU on Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long ll; 21 | 22 | const int N = 123456; 23 | const int INF = 1e9 + 10; 24 | 25 | ll ans[N]; 26 | int n, c[N]; 27 | vector g[N]; 28 | 29 | void dfs (int u, int from, map &f) { 30 | for (int v : g[u]) { 31 | if (v == from) continue; 32 | map h; 33 | dfs(v, u, h); 34 | if (h.size() > f.size()) f.swap(h); 35 | for (auto it : h) { 36 | if (it.first >= INF) { 37 | continue; 38 | } 39 | f[it.first] += it.second; 40 | if (f[it.first] > f[INF]) { 41 | f[INF] = f[it.first]; 42 | f[INF + 1] = it.first; 43 | } else if (f[it.first] == f[INF]) { 44 | f[INF + 1] += it.first; 45 | } 46 | } 47 | } 48 | ++f[c[u]]; 49 | if (f[c[u]] > f[INF]) { 50 | f[INF] = f[c[u]]; 51 | f[INF + 1] = c[u]; 52 | } else if (f[c[u]] == f[INF]) { 53 | f[INF + 1] += c[u]; 54 | } 55 | ans[u] = f[INF + 1]; 56 | } 57 | 58 | int main() { 59 | scanf("%d", &n); 60 | for (int i = 1; i <= n; ++i) { 61 | scanf("%d", c + i); 62 | } 63 | for (int i = 1; i < n; ++i) { 64 | int u, v; 65 | scanf("%d %d", &u, &v); 66 | g[u].push_back(v); 67 | g[v].push_back(u); 68 | } 69 | map f; 70 | dfs(1, 1, f); 71 | for (int i = 1; i <= n; ++i) { 72 | printf("%lld ", ans[i]); 73 | } 74 | puts(""); 75 | return 0; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /Codeforces - Number of Ways.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 466C - Number of Ways 9 | 10 | Category: Ad hoc 11 | 12 | Keys: Simplification 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (i64) 1e14 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX 500005 31 | 32 | vector V; 33 | i64 A[MAX], C[MAX], S, n, i, Count, Ret; 34 | 35 | int main() { 36 | cin.tie(nullptr); 37 | ios_base::sync_with_stdio(0); 38 | 39 | cin >> n; 40 | for (i = 1; i <= n; i++) 41 | cin >> A[i], 42 | C[i] = C[i - 1] + A[i]; 43 | 44 | if (C[n] % 3 || n <= 2) { 45 | cout << 0 << endl; 46 | return 0; 47 | } 48 | 49 | S = C[n]/3, Count = Ret = 0; 50 | 51 | if (S == 0) { 52 | for (i = 1; i < n; i++) 53 | if (C[i] == 0) ++Count; 54 | 55 | Ret = Count * (Count - 1)/2; 56 | cout << Ret << endl; 57 | return 0; 58 | } 59 | 60 | for (i = 1; i < n; i++) { 61 | if (C[i] == S) V.push_back(0); 62 | 63 | else if (C[i] == S + S && !V.empty()) 64 | V.push_back(1), ++Count; 65 | } 66 | 67 | S = V.size(); 68 | 69 | for (i = 0; i < S; i++) { 70 | if (V[i] == 0) Ret += Count; 71 | else --Count; 72 | } 73 | 74 | cout << Ret << endl; 75 | 76 | cout.flush(); 77 | return 0; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /Codeforces - Product Sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 631E - Product Sum 9 | 10 | Category: Data Structures 11 | 12 | Keys: Algebraic Manipulation, Convex Hull Trick 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 2e5 + 10; 21 | 22 | int n; 23 | long long a[N]; 24 | long long sum[N]; 25 | vector m; 26 | vector c; 27 | int size; 28 | 29 | bool bad (int l1, int l2, int l3, int forward) { 30 | if (forward) return (c[l1] - c[l2]) * (m[l3] - m[l1]) >= (c[l1] - c[l3]) * (m[l2] - m[l1]); 31 | return (c[l2] - c[l1]) * (m[l1] - m[l3]) <= (c[l3] - c[l1]) * (m[l1] - m[l2]); 32 | } 33 | 34 | void add (long long m0, long long c0, int forward) { 35 | ++size; 36 | m.push_back(m0); 37 | c.push_back(c0); 38 | while (size >= 3 and bad(size - 3, size - 2, size - 1, forward)) { 39 | --size; 40 | m.erase(m.end() - 2); 41 | c.erase(c.end() - 2); 42 | } 43 | } 44 | 45 | long long query (long long x) { 46 | long long last = m[size - 1] * x + c[size - 1]; 47 | int lo = 0, hi = size - 2; 48 | while (lo < hi) { 49 | int mid = lo + hi >> 1; 50 | long long now = m[mid] * x + c[mid]; 51 | long long after = m[mid + 1] * x + c[mid + 1]; 52 | if (now < after) lo = mid + 1; 53 | else hi = mid; 54 | } 55 | return max(last, m[lo] * x + c[lo]); 56 | } 57 | 58 | int main (int argc, char const *argv[]) { 59 | scanf("%d", &n); 60 | long long res = 0; 61 | for (int i = 1; i <= n; ++i) { 62 | scanf("%lld", a + i); 63 | sum[i] = a[i] + sum[i - 1]; 64 | res += a[i] * i; 65 | } 66 | long long delta = 0; 67 | size = 0; 68 | add(n, -sum[n], 0); 69 | for (int i = n - 1; i; --i) { 70 | delta = max(delta, sum[i] - a[i] * i + query(a[i])); 71 | add(i, -sum[i], 0); 72 | } 73 | m.clear(), c.clear(); 74 | size = 0; 75 | add(1, -sum[0], 1); 76 | for (int i = 2; i <= n; ++i) { 77 | delta = max(delta, sum[i - 1] - a[i] * i + query(a[i])); 78 | add(i, -sum[i - 1], 1); 79 | } 80 | printf("%lld\n", res + delta); 81 | return 0; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /Codeforces - Tree Requests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 570D - Tree Requests 9 | 10 | Category: Graph Theory 11 | 12 | Keys: DSU on Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef pair data; 21 | 22 | #define x first 23 | #define y second 24 | 25 | const int N = 500010; 26 | 27 | char s[N]; 28 | int n, m, h[N]; 29 | vector g[N]; 30 | vector q[N]; 31 | bitset ans; 32 | 33 | void go (int u, int deep = 1) { 34 | h[u] = deep; 35 | for (int v : g[u]) { 36 | go(v, deep + 1); 37 | } 38 | } 39 | 40 | void dfs (int u, map &f) { 41 | for (int v : g[u]) { 42 | map t; 43 | dfs(v, t); 44 | if (t.size() > f.size()) f.swap(t); 45 | for (auto it : t) { 46 | f[it.x] ^= it.y; 47 | } 48 | } 49 | f[h[u]] ^= 1 << (s[u] - 'a'); 50 | for (data it : q[u]) { 51 | if (f.find(it.x) == f.end()) { 52 | ans[it.y] = 1; 53 | } 54 | if ((f[it.x] & (f[it.x] - 1)) == 0) { 55 | ans[it.y] = 1; 56 | } 57 | } 58 | } 59 | 60 | int main() { 61 | scanf("%d %d", &n, &m); 62 | for (int i = 2; i <= n; ++i) { 63 | int par; 64 | scanf("%d", &par); 65 | g[par].push_back(i); 66 | } 67 | go(1); 68 | scanf("%s", s + 1); 69 | for (int i = 1; i <= m; ++i) { 70 | int u, h; 71 | scanf("%d %d", &u, &h); 72 | q[u].emplace_back(h, i); 73 | } 74 | map f; 75 | dfs(1, f); 76 | for (int i = 1; i <= m; ++i) { 77 | puts(ans[i] ? "Yes" : "No"); 78 | } 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /Codeforces - Tree-String Problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 291E - Tree-String Problem 9 | 10 | Category: Graph Theory 11 | 12 | Keys: DFS, Hashing, Binary Jump 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long ll; 21 | typedef pair edge; 22 | 23 | const int P = 29; 24 | const int LG = 20; 25 | const int N = 1234567; 26 | const int MOD = 1e9 + 7; 27 | int INV; 28 | 29 | string s; 30 | ll hashVal[N]; 31 | vector g[N]; 32 | int n, m, k, ans; 33 | int h[N], par[N][LG]; 34 | 35 | ll bigMod (ll a, int e) { 36 | if (e == -1) e = MOD - 2; 37 | ll r = 1; while (e) { 38 | if (e & 1) r = (r * a) % MOD; 39 | a = (a * a) % MOD; 40 | e >>= 1; 41 | } 42 | return r; 43 | } 44 | 45 | void dfs (int u, int deep = 0) { 46 | h[u] = deep; 47 | for (edge e : g[u]) { 48 | int v = e.first, w = e.second; 49 | par[v][0] = u; 50 | hashVal[v] = (hashVal[u] + w * bigMod(P, deep)) % MOD; 51 | dfs(v, deep + 1); 52 | } 53 | } 54 | 55 | int ancestor (int u, int k) { 56 | if (h[u] < k) return -1; 57 | for (int i = LG - 1; i >= 0; --i) { 58 | if (k >= (1 << i)) { 59 | k -= (1 << i); 60 | u = par[u][i]; 61 | } 62 | } 63 | return u; 64 | } 65 | 66 | void go (int u) { 67 | int v = ancestor(u, k); 68 | if (v != -1) { 69 | ll cur = (hashVal[u] - hashVal[v]) * bigMod(INV, h[v]); 70 | cur %= MOD, cur += MOD, cur %= MOD; 71 | if (cur == hashVal[0]) { 72 | ++ans; 73 | } 74 | } 75 | for (edge e : g[u]) { 76 | int v = e.first; 77 | go(v); 78 | } 79 | } 80 | 81 | int main() { 82 | cin.tie(nullptr); 83 | ios_base::sync_with_stdio(false); 84 | 85 | INV = bigMod(P, -1); 86 | cin >> n; 87 | m = n; 88 | for (int i = 2; i <= n; ++i) { 89 | string x; 90 | int par, sz; 91 | cin >> par >> x; 92 | sz = x.size(); 93 | for (int i = 0; i < sz - 1; ++i) { 94 | g[par].emplace_back(++m, x[i] - 'a' + 1); 95 | par = m; 96 | } 97 | g[par].emplace_back(i, x[sz - 1] - 'a' + 1); 98 | } 99 | cin >> s; 100 | k = s.size(); 101 | hashVal[0] = 0; 102 | for (int i = 0; i < k; ++i) { 103 | hashVal[0] += (s[i] - 'a' + 1) * bigMod(P, i); 104 | hashVal[0] %= MOD; 105 | } 106 | memset(par, -1, sizeof par); 107 | dfs(1); 108 | for (int i = 1; i < LG; ++i) { 109 | for (int j = 1; j <= m; ++j) { 110 | if (par[j][i - 1] != -1) { 111 | par[j][i] = par[par[j][i - 1]][i - 1]; 112 | } 113 | } 114 | } 115 | go(1); 116 | printf("%d\n", ans); 117 | return 0; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /Codeforces - Water Tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 343D - Water Tree 9 | 10 | Category: Data Structures 11 | 12 | Keys: DFS, Tree Flattening, Segment Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 5e5 + 10; 21 | 22 | bitset vis; 23 | vector g[N]; 24 | int n, q, pointer = 0; 25 | int preOrder[N], p[N], l[N], r[N]; 26 | int tree[3 * N], lazy[3 * N]; 27 | 28 | void dfs (int u) { 29 | vis[u] = 1; 30 | preOrder[++pointer] = u; 31 | l[u] = pointer; 32 | for (int v : g[u]) if (!vis[v]) p[v] = u, dfs(v); 33 | r[u] = pointer; 34 | } 35 | 36 | void propagate (int u, int b, int e) { 37 | tree[u] = e - b + 1; 38 | if (b != e) lazy[u << 1] = lazy[u << 1 | 1] = 1; 39 | lazy[u] = 0; 40 | } 41 | 42 | void build (int u, int b, int e) { 43 | if (b == e) { 44 | tree[u] = 2; 45 | return; 46 | } 47 | 48 | int l = u << 1, r = l | 1, m = b + e >> 1; 49 | build(l, b, m), build(r, m + 1, e); 50 | tree[u] = tree[l] + tree[r]; 51 | } 52 | 53 | void rangeFill (int u, int b, int e, int p, int q) { 54 | if (lazy[u]) propagate(u, b, e); 55 | if (b > q or e < p) return; 56 | if (b >= p and e <= q) { 57 | lazy[u] = 1, propagate(u, b, e); 58 | return; 59 | } 60 | 61 | int l = u << 1, r = l | 1, m = b + e >> 1; 62 | rangeFill(l, b, m, p, q), rangeFill(r, m + 1, e, p, q); 63 | tree[u] = tree[l] + tree[r]; 64 | } 65 | 66 | void pointColor (int u, int b, int e, int p) { 67 | if (lazy[u]) propagate(u, b, e); 68 | if (b > p or e < p) return; 69 | if (b == e) { 70 | tree[u] = 2; 71 | return; 72 | } 73 | 74 | int l = u << 1, r = l | 1, m = b + e >> 1; 75 | pointColor(l, b, m, p), pointColor(r, m + 1, e, p); 76 | tree[u] = tree[l] + tree[r]; 77 | } 78 | 79 | int query (int u, int b, int e, int p, int q) { 80 | if (b > q or e < p) return 0; 81 | if (lazy[u]) propagate(u, b, e); 82 | if (b >= p and e <= q) return tree[u]; 83 | 84 | int l = u << 1, r = l | 1, m = b + e >> 1; 85 | return query(l, b, m, p, q) + query(r, m + 1, e, p, q); 86 | } 87 | 88 | int main (int argc, char const *argv[]) { 89 | scanf("%d", &n); 90 | for (int i = 1; i < n; ++i) { 91 | int u, v; 92 | scanf("%d %d", &u, &v); 93 | g[u].push_back(v); 94 | g[v].push_back(u); 95 | } 96 | 97 | dfs(1), build(1, 1, n); 98 | 99 | scanf("%d", &q); while (q--) { 100 | int cmd, u; 101 | scanf("%d %d", &cmd, &u); 102 | 103 | if (cmd == 1) { 104 | int subtreeSum = query(1, 1, n, l[u], r[u]); 105 | if (subtreeSum > r[u] - l[u] + 1) pointColor(1, 1, n, l[p[u]]); 106 | rangeFill(1, 1, n, l[u], r[u]); 107 | } else if (cmd == 2) { 108 | pointColor(1, 1, n, l[u]); 109 | } else { 110 | int subtreeSum = query(1, 1, n, l[u], r[u]); 111 | if (subtreeSum > r[u] - l[u] + 1) puts("0"); 112 | else puts("1"); 113 | } 114 | } 115 | return 0; 116 | } 117 | 118 | -------------------------------------------------------------------------------- /Codeforces - Xenia and Bit Operation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Codeforces 339D - Xenia and Bit Operation 9 | 10 | Category: Data Structure 11 | 12 | Keys: Segment Tree, I/O Optimization 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (i64) 1e14 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | const int MAX = (1 << 17) + 50; 32 | 33 | int A[MAX], T[4 * MAX], n, lim, q, p, v; 34 | 35 | void Build (int node, int b, int e, int dist) { 36 | if (b == e) { 37 | T[node] = A[b]; 38 | return; 39 | } 40 | 41 | int mid = (b + e) >> 1; 42 | int left = node + node; 43 | int right = left + 1; 44 | 45 | Build (left, b, mid, dist - 1); 46 | Build (right, mid + 1, e, dist - 1); 47 | 48 | if (dist & 1) T[node] = T[left] | T[right]; 49 | else T[node] = T[left] ^ T[right]; 50 | } 51 | 52 | void Update (int node, int b, int e, int pos, int val, int dist) { 53 | if (b > pos or e < pos) return; 54 | if (b == e and b == pos) { 55 | T[node] = val; 56 | return; 57 | } 58 | 59 | int mid = (b + e) >> 1; 60 | int left = node + node; 61 | int right = left + 1; 62 | 63 | Update (left, b, mid, pos, val, dist - 1); 64 | Update (right, mid + 1, e, pos, val, dist - 1); 65 | 66 | if (dist & 1) T[node] = T[left] | T[right]; 67 | else T[node] = T[left] ^ T[right]; 68 | } 69 | 70 | int main() { 71 | scanf("%d %d", &n, &q); 72 | lim = 1 << n; 73 | for (int i = 1; i <= lim; i++) scanf("%d", A + i); 74 | 75 | Build (1, 1, lim, n); 76 | 77 | while (q--) { 78 | scanf("%d %d", &p, &v); 79 | Update (1, 1, lim, p, v, n); 80 | printf("%d\n", T[1]); 81 | } 82 | return 0; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /HackerEarth - Relatives.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | HackerEarth - Relatives 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Pointer Walk 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 105; 21 | const int OO = 2e9 + 50; 22 | 23 | pair DP[N][N][N]; 24 | int K, a, b, c, A[N], B[N], C[N]; 25 | 26 | int main (int argc, char const *argv[]) { 27 | scanf("%d %d %d %d", &a, &b, &c, &K); 28 | for (int i = 0; i < a; ++i) scanf("%d", A + i); 29 | for (int i = 0; i < b; ++i) scanf("%d", B + i); 30 | for (int i = 0; i < c; ++i) scanf("%d", C + i); 31 | 32 | for (int i = 0; i <= a; ++i) 33 | for (int j = 0; j <= b; ++j) 34 | for (int k = 0; k <= c; ++k) 35 | DP[i][j][k] = make_pair(OO, OO); 36 | 37 | DP[0][0][0] = make_pair(1, 0); 38 | 39 | for (int i = 0; i <= a; ++i) 40 | for (int j = 0; j <= b; ++j) 41 | for (int k = 0; k <= c; ++k) { 42 | if (i < a) { 43 | int Min = DP[i][j][k].first, Cost = DP[i][j][k].second + A[i]; 44 | if (Cost > K) Cost = A[i], ++Min; 45 | DP[i + 1][j][k] = min(DP[i + 1][j][k], make_pair(Min, Cost)); 46 | } 47 | 48 | if (j < b) { 49 | int Min = DP[i][j][k].first, Cost = DP[i][j][k].second + B[j]; 50 | if (Cost > K) Cost = B[j], ++Min; 51 | DP[i][j + 1][k] = min(DP[i][j + 1][k], make_pair(Min, Cost)); 52 | } 53 | 54 | if (k < c) { 55 | int Min = DP[i][j][k].first, Cost = DP[i][j][k].second + C[k]; 56 | if (Cost > K) Cost = C[k], ++Min; 57 | DP[i][j][k + 1] = min(DP[i][j][k + 1], make_pair(Min, Cost)); 58 | } 59 | } 60 | 61 | printf("%d\n", DP[a][b][c]); 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /HackerEarth - The Grass Type.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | |\ | `|` |``\ ```|` | | /```\ |``\ 3 | | \ | | |__/ | |___| | | |__/ 4 | | \ | | | \ | | | | | | \ 5 | _| \| _|_ | \ \__) | | \___/ | \ 6 | 7 | HackerEarth - The Grass Type 8 | 9 | Category: Graph Theory 10 | 11 | Keys: DSU on Tree 12 | 13 | */ 14 | 15 | #include 16 | 17 | using namespace std; 18 | 19 | const int N = 100010; 20 | 21 | int n, m, w[N]; 22 | vector g[N]; 23 | long long ans; 24 | 25 | void dfs (int u, int from, map &f) { 26 | ++f[w[u]]; 27 | for (int v : g[u]) { 28 | if (v == from) continue; 29 | map t; 30 | dfs(v, u, t); 31 | if (t.size() > f.size()) { 32 | f.swap(t); 33 | } 34 | for (auto it : t) { 35 | if (w[u] % it.first == 0 and f.find(w[u] / it.first) != f.end()) { 36 | ans += it.second * 1LL * f[w[u] / it.first]; 37 | } 38 | } 39 | for (auto it : t) { 40 | f[it.first] += it.second; 41 | } 42 | } 43 | } 44 | 45 | int main() { 46 | scanf("%d", &n); 47 | for (int i = 1; i < n; ++i) { 48 | int u, v; 49 | scanf("%d %d", &u, &v); 50 | g[u].push_back(v); 51 | g[v].push_back(u); 52 | } 53 | for (int i = 1; i <= n; ++i) { 54 | scanf("%d", w + i); 55 | } 56 | map f; 57 | dfs(1, 1, f); 58 | printf("%lld\n", ans); 59 | return 0; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /IOI 2013 - Dreaming.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | IOI 2013 - Dreaming 9 | 10 | Category: Graph Theory 11 | 12 | Keys: DFS, Observation 13 | 14 | */ 15 | 16 | #include 17 | #include "dreaming.h" 18 | 19 | using namespace std; 20 | 21 | typedef pair edge; 22 | 23 | #define to first 24 | #define cost second 25 | 26 | const int MAX = 123456; 27 | 28 | bitset vis; 29 | vector g[MAX]; 30 | int maxDist, at; 31 | edge par[MAX]; 32 | 33 | void dfs (int u, int from, int far, int flag) { 34 | if (flag) { 35 | vis[u] = 1; 36 | } 37 | if (far > maxDist) { 38 | maxDist = far; 39 | at = u; 40 | } 41 | for (edge e : g[u]) { 42 | if (e.to == from) continue; 43 | if (flag) { 44 | par[e.to] = edge(u, e.cost); 45 | } 46 | dfs(e.to, u, far + e.cost, flag); 47 | } 48 | } 49 | 50 | int travelTime (int N, int M, int L, int A[], int B[], int T[]) { 51 | for (int i = 0; i < M; ++i) { 52 | g[A[i]].emplace_back(B[i], T[i]); 53 | g[B[i]].emplace_back(A[i], T[i]); 54 | } 55 | 56 | vector R; 57 | int ret = 0; 58 | for (int i = 0; i < N; ++i) { 59 | if (vis[i]) continue; 60 | maxDist = -1; 61 | dfs(i, i, 0, 0); 62 | int one = at; 63 | maxDist = -1; 64 | dfs(one, one, 0, 1); 65 | int two = at; 66 | 67 | ret = max(ret, maxDist); 68 | 69 | int half = maxDist >> 1; 70 | int radius = 0; 71 | for (int v = two; v != one; v = par[v].to) { 72 | if (radius + par[v].cost > half) { 73 | radius = min(radius + par[v].cost, maxDist - radius); 74 | break; 75 | } 76 | radius += par[v].cost; 77 | } 78 | R.push_back(radius); 79 | } 80 | 81 | sort(R.rbegin(), R.rend()); 82 | if (R.size() > 1) ret = max(ret, R[0] + R[1] + L); 83 | if (R.size() > 2) ret = max(ret, R[1] + R[2] + L + L); 84 | return ret; 85 | } 86 | 87 | -------------------------------------------------------------------------------- /IOI 2014 - Wall.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | IOI 2014 - Wall 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree, Lazy Propagation 13 | 14 | */ 15 | 16 | #include 17 | #include "wall.h" 18 | 19 | using namespace std; 20 | 21 | typedef pair node; 22 | 23 | #define Min first 24 | #define Max second 25 | 26 | const int N = 2000010; 27 | const int INF = 1e9 + 10; 28 | 29 | node tree[4 * N]; 30 | 31 | void push (int u, int b, int e) { 32 | if (b == e) return; 33 | int l = u << 1, r = l | 1; 34 | tree[l].Min = min(tree[l].Min, tree[u].Min); 35 | tree[l].Min = max(tree[l].Min, tree[u].Max); 36 | tree[l].Max = min(tree[l].Max, tree[u].Min); 37 | tree[l].Max = max(tree[l].Max, tree[u].Max); 38 | tree[r].Min = min(tree[r].Min, tree[u].Min); 39 | tree[r].Min = max(tree[r].Min, tree[u].Max); 40 | tree[r].Max = min(tree[r].Max, tree[u].Min); 41 | tree[r].Max = max(tree[r].Max, tree[u].Max); 42 | } 43 | 44 | void update (int u, int b, int e, int from, int to, int v, int type) { 45 | push(u, b, e); 46 | if (b > to or e < from) return; 47 | if (b >= from and e <= to) { 48 | if (type) { 49 | tree[u].Min = min(tree[u].Min, v); 50 | tree[u].Max = min(tree[u].Max, v); 51 | } else { 52 | tree[u].Min = max(tree[u].Min, v); 53 | tree[u].Max = max(tree[u].Max, v); 54 | } 55 | return; 56 | } 57 | tree[u].Min = INF, tree[u].Max = -INF; 58 | int l = u << 1, r = l | 1, m = b + e >> 1; 59 | update(l, b, m, from, to, v, type); 60 | update(r, m + 1, e, from, to, v, type); 61 | } 62 | 63 | void traverse (int u, int b, int e, int res[]) { 64 | if (b == e) { 65 | res[b - 1] = tree[u].Min; 66 | return; 67 | } 68 | push(u, b, e); 69 | int l = u << 1, r = l | 1, m = b + e >> 1; 70 | traverse(l, b, m, res), traverse(r, m + 1, e, res); 71 | } 72 | 73 | void buildWall (int n, int k, int op[], int left[], int right[], int height[], int finalHeight[]) { 74 | for (int i = 0; i < k; ++i) { 75 | update(1, 1, n, left[i] + 1, right[i] + 1, height[i], op[i] - 1); 76 | } 77 | traverse(1, 1, n, finalHeight); 78 | return; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /IOI 2015 - Boxes with souvenirs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | IOI 2015 - Boxes with souvenirs 9 | 10 | Category: Ad hoc 11 | 12 | Keys: Observation, Constructive Algorithms 13 | 14 | */ 15 | 16 | #include 17 | #include "boxes.h" 18 | 19 | using namespace std; 20 | 21 | vector costLeft; 22 | vector costRight; 23 | 24 | long long delivery (int N, int K, int L, int p[]) { 25 | int mid = L >> 1; 26 | for (int i = 0; i < N; ++i) { 27 | if (p[i] > mid) { 28 | costRight.push_back(2LL * (L - p[i])); 29 | } else { 30 | costLeft.push_back(2LL * p[i]); 31 | } 32 | } 33 | reverse(costRight.begin(), costRight.end()); 34 | int sizeLeft = (int) costLeft.size(); 35 | int sizeRight = (int) costRight.size(); 36 | for (int i = K; i < sizeLeft; ++i) { 37 | costLeft[i] += costLeft[i - K]; 38 | } 39 | for (int i = K; i < sizeRight; ++i) { 40 | costRight[i] += costRight[i - K]; 41 | } 42 | long long leftCost = sizeLeft ? costLeft[sizeLeft - 1] : 0; 43 | long long rightCost = sizeRight ? costRight[sizeRight - 1] : 0; 44 | long long ret = leftCost + rightCost; 45 | for (int i = 0; i <= K; ++i) { 46 | int leftTaken = i, rightTaken = K - i; 47 | long long left = leftTaken >= sizeLeft ? 0 : costLeft[sizeLeft - 1 - leftTaken]; 48 | long long right = rightTaken >= sizeRight ? 0 : costRight[sizeRight - 1 - rightTaken]; 49 | ret = min(ret, L + left + right); 50 | } 51 | return ret; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /IOI 2015 - Horses.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | IOI 2015 - Horses 9 | 10 | Category: Data Structures 11 | 12 | Keys: Observation, Segment Tree, Algebra 13 | 14 | */ 15 | 16 | #include 17 | #include "horses.h" 18 | 19 | using namespace std; 20 | 21 | typedef long long ll; 22 | typedef long double ld; 23 | 24 | const ld EPS = 1e-9; 25 | const int N = 5e5 + 10; 26 | const int MOD = 1e9 + 7; 27 | 28 | int n; 29 | ll x[N], y[N]; 30 | int tree[4 * N]; 31 | ld xlog[N], ylog[N]; 32 | ll product[N + N]; 33 | ld logsum[N + N]; 34 | 35 | void init_product (void) { 36 | for (int i = 0; i < n; ++i) { 37 | product[n + i] = x[i] % MOD; 38 | } 39 | for (int i = n - 1; i; --i) { 40 | product[i] = (product[i << 1] * product[i << 1 | 1]) % MOD; 41 | } 42 | } 43 | 44 | void modify_product (int p, ll v) { 45 | for (product[p += n] = v; p > 1; p >>= 1) { 46 | product[p >> 1] = (product[p] * product[p ^ 1]) % MOD; 47 | } 48 | } 49 | 50 | ll find_product (int l, int r) { 51 | ll ret = 1LL; 52 | for (l += n, r += n; l < r; l >>= 1, r >>= 1) { 53 | if (l & 1) ret *= product[l++], ret %= MOD; 54 | if (r & 1) ret *= product[--r], ret %= MOD; 55 | } 56 | return ret; 57 | } 58 | 59 | void init_logsum (void) { 60 | for (int i = 0; i < n; ++i) { 61 | logsum[n + i] = xlog[i]; 62 | } 63 | for (int i = n - 1; i; --i) { 64 | logsum[i] = logsum[i << 1] + logsum[i << 1 | 1]; 65 | } 66 | } 67 | 68 | void modify_logsum (int p, ld v) { 69 | for (logsum[p += n] = v; p > 1; p >>= 1) { 70 | logsum[p >> 1] = logsum[p] + logsum[p ^ 1]; 71 | } 72 | } 73 | 74 | ld find_logsum (int l, int r) { 75 | ld ret = 0.0; 76 | for (l += n, r += n; l < r; l >>= 1, r >>= 1) { 77 | if (l & 1) ret += logsum[l++]; 78 | if (r & 1) ret += logsum[--r]; 79 | } 80 | return ret; 81 | } 82 | 83 | int merged (int p, int q) { 84 | if (p > q) swap(p, q); 85 | return (find_logsum(p + 1, q + 1) - ylog[p] + ylog[q] > -EPS) ? q : p; 86 | } 87 | 88 | void init_tree (int u, int b, int e) { 89 | if (b == e) { 90 | tree[u] = b; 91 | return; 92 | } 93 | int l = u << 1, r = l | 1, m = b + e >> 1; 94 | init_tree(l, b, m), init_tree(r, m + 1, e); 95 | tree[u] = merged(tree[l], tree[r]); 96 | } 97 | 98 | void modify_tree (int u, int b, int e, int p) { 99 | if (b > p or e < p) return; 100 | if (b == e) return; 101 | int l = u << 1, r = l | 1, m = b + e >> 1; 102 | modify_tree(l, b, m, p), modify_tree(r, m + 1, e, p); 103 | tree[u] = merged(tree[l], tree[r]); 104 | } 105 | 106 | ll value (int index) { 107 | return (find_product(0, index + 1) * y[index]) % MOD; 108 | } 109 | 110 | int init (int N, int X[], int Y[]) { 111 | n = N; 112 | for (int i = 0; i < n; ++i) { 113 | x[i] = X[i], y[i] = Y[i]; 114 | xlog[i] = log(x[i]), ylog[i] = log(y[i]); 115 | } 116 | init_product(); 117 | init_logsum(); 118 | init_tree(1, 0, n - 1); 119 | return value(tree[1]); 120 | } 121 | 122 | int updateX (int pos, int val) { 123 | x[pos] = val, xlog[pos] = log(val); 124 | modify_product(pos, x[pos]); 125 | modify_logsum(pos, xlog[pos]); 126 | modify_tree(1, 0, n - 1, pos); 127 | return value(tree[1]); 128 | } 129 | 130 | int updateY (int pos, int val) { 131 | y[pos] = val, ylog[pos] = log(val); 132 | modify_tree(1, 0, n - 1, pos); 133 | return value(tree[1]); 134 | } 135 | 136 | -------------------------------------------------------------------------------- /IOI 2016 - Detecting Molecules.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | IOI 2016 - Detecting Molecules 9 | 10 | Category: Ad hoc 11 | 12 | Keys: Observation, Two Pointers 13 | 14 | */ 15 | 16 | #include 17 | #include "molecules.h" 18 | 19 | using namespace std; 20 | 21 | typedef long long ll; 22 | typedef pair pii; 23 | 24 | vector find_subset (int l, int u, vector w) { 25 | int n = w.size(); 26 | vector v; 27 | for (int i = 0; i < n; ++i) { 28 | v.push_back(pii(w[i], i)); 29 | } 30 | sort(v.begin(), v.end()); 31 | ll sum = 0; 32 | vector r; 33 | for (int i = 0, j = 0; j < n; ++j) { 34 | sum += v[j].first; 35 | while (sum > u) { 36 | sum -= v[i++].first; 37 | } 38 | if (sum >= l) { 39 | for (int k = i; k <= j; ++k) { 40 | r.push_back(v[k].second); 41 | } 42 | break; 43 | } 44 | } 45 | return r; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /IOI 2016 - Paint By Numbers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | IOI 2016 - Paint By Numbers 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Casework 13 | 14 | */ 15 | 16 | #include 17 | #include "paint.h" 18 | 19 | using namespace std; 20 | 21 | const int K = 105; 22 | const int N = 200010; 23 | 24 | string s; 25 | vector c; 26 | int x[N], u[N]; 27 | int n, k, tot[N]; 28 | int dp[N][K]; 29 | 30 | int u_in_range (int l, int r) { 31 | return tot[r] - (l > 0 ? tot[l - 1] : 0); 32 | } 33 | 34 | void update_x (int l, int r) { 35 | ++x[l], --x[r + 1]; 36 | } 37 | 38 | void update_u (int l, int r) { 39 | ++u[l], --u[r + 1]; 40 | } 41 | 42 | int call (int at, int block) { 43 | if (at >= n) return block == k; 44 | int &ret = dp[at][block]; 45 | if (ret != -1) return ret; 46 | ret = 0; 47 | if (block == k) { 48 | if (s[at] == '_') { 49 | ret = call(at + 1, block); 50 | if (ret) update_u(at, at); 51 | return ret; 52 | } else if (s[at] == '.') { 53 | ret = call(at + 1, block); 54 | if (ret) update_u(at, at); 55 | return ret; 56 | } else { 57 | return ret = 0; 58 | } 59 | } 60 | if (s[at] == '_') { 61 | ret = call(at + 1, block); 62 | if (ret) update_u(at, at); 63 | return ret; 64 | } 65 | if (s[at] == 'X') { 66 | int nxt = at + c[block]; 67 | if (nxt > n) return ret = 0; 68 | if (u_in_range(at, nxt - 1) > 0) { 69 | return ret = 0; 70 | } 71 | if (nxt < n and s[nxt] == 'X') { 72 | return ret = 0; 73 | } 74 | ret = call(nxt + 1, block + 1); 75 | if (ret) { 76 | if (nxt < n) { 77 | update_u(nxt, nxt); 78 | } 79 | update_x(at, nxt - 1); 80 | } 81 | return ret; 82 | } 83 | int one = call(at + 1, block); 84 | if (one) update_u(at, at); 85 | int two, nxt = at + c[block]; 86 | if (nxt > n) two = 0; 87 | else if (u_in_range(at, nxt - 1) > 0) { 88 | two = 0; 89 | } else if (nxt < n and s[nxt] == 'X') { 90 | two = 0; 91 | } else { 92 | two = call(nxt + 1, block + 1); 93 | if (two) { 94 | if (nxt < n) { 95 | update_u(nxt, nxt); 96 | } 97 | update_x(at, nxt - 1); 98 | } 99 | } 100 | return ret = one | two; 101 | } 102 | 103 | string solve_puzzle (string s_in, vector c_in) { 104 | s = s_in, c = c_in; 105 | n = s.size(), k = c.size(); 106 | memset(dp, -1, sizeof dp); 107 | for (int i = 0; i < n; ++i) { 108 | if (i > 0) tot[i] = tot[i - 1]; 109 | if (s[i] == '_') { 110 | ++tot[i]; 111 | } 112 | } 113 | call(0, 0); 114 | string res = ""; 115 | for (int i = 0; i < n; ++i) { 116 | if (i) { 117 | x[i] += x[i - 1]; 118 | u[i] += u[i - 1]; 119 | } 120 | if (x[i] and u[i]) res += '?'; 121 | else if (x[i]) res += 'X'; 122 | else res += '_'; 123 | } 124 | return res; 125 | } 126 | 127 | -------------------------------------------------------------------------------- /IOI 2016 - Roller Coaster Railroad.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | IOI 2016 - Roller Coaster Railroad 9 | 10 | Category: Graph Theory 11 | 12 | Keys: Observation, Minimum Spanning Tree 13 | 14 | */ 15 | 16 | #include 17 | #include "railroad.h" 18 | 19 | using namespace std; 20 | 21 | struct data { 22 | int x, y, z; 23 | data () {} 24 | data (int _x, int _y, int _z) { 25 | x = _x, y = _y, z = _z; 26 | } 27 | bool operator < (const data &d) const { 28 | return x < d.x; 29 | } 30 | }; 31 | 32 | const int INF = 2e9 + 10; 33 | 34 | vector p; 35 | 36 | int find (int x) { 37 | return p[x] == x ? x : p[x] = find(p[x]); 38 | } 39 | 40 | bool merge (int x, int y) { 41 | x = find(x), y = find(y); 42 | return p[x] = y, x != y; 43 | } 44 | 45 | long long plan_roller_coaster (vector s, vector t) { 46 | s.push_back(INF); 47 | t.push_back(1); 48 | int n = (int) s.size(); 49 | for (int i = 0; i < n; ++i) { 50 | p.push_back(i); 51 | } 52 | vector good, edge; 53 | for (int i = 0; i < n; ++i) { 54 | good.emplace_back(s[i], i, 1); 55 | good.emplace_back(t[i], i, -1); 56 | } 57 | sort(good.begin(), good.end()); 58 | long long ans = 0; 59 | for (int i = 0, diff = 0; i + 1 < n + n; ++i) { 60 | diff += good[i].z; 61 | ans += max(0, diff) * 1LL * (good[i + 1].x - good[i].x); 62 | edge.emplace_back(good[i + 1].x - good[i].x, good[i].y, good[i + 1].y); 63 | if ((diff != 0) or (good[i].x == good[i + 1].x)) { 64 | merge(good[i].y, good[i + 1].y); 65 | } 66 | } 67 | sort(edge.begin(), edge.end()); 68 | for (int i = 0; i + 1 < n + n; ++i) { 69 | if (merge(edge[i].y, edge[i].z)) { 70 | ans += 1LL * edge[i].x; 71 | } 72 | } 73 | return ans; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /IOI 2016 - Unscrambling a Messy Bug.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | IOI 2016 - Unscrambling a Messy Bug 9 | 10 | Category: Divide and Conquer 11 | 12 | Keys: Constructive Algorithms 13 | 14 | */ 15 | 16 | #include 17 | #include "messy.h" 18 | 19 | using namespace std; 20 | 21 | void go (int n, int l, int r) { 22 | if (l + 1 == r) return; 23 | int m = l + r >> 1; 24 | string s = ""; 25 | for (int i = 0; i < n; ++i) { 26 | s += '1'; 27 | } 28 | for (int i = l; i < r; ++i) { 29 | s[i] = '0'; 30 | } 31 | for (int i = l; i < m; ++i) { 32 | s[i] = '1'; 33 | add_element(s); 34 | s[i] = '0'; 35 | } 36 | go(n, l, m); 37 | go(n, m, r); 38 | } 39 | 40 | vector v; 41 | 42 | void kill (int n, int l, int r, string no) { 43 | if (l + 1 == r) { 44 | for (int i = 0; i < n; ++i) { 45 | if (no[i] == '0') { 46 | v[i] = l; 47 | break; 48 | } 49 | } 50 | return; 51 | } 52 | string x = no, y = ""; 53 | for (int i = 0; i < n; ++i) { 54 | y += '1'; 55 | } 56 | for (int i = 0; i < n; ++i) { 57 | if (no[i] == '0') { 58 | no[i] = '1'; 59 | if (check_element(no)) { 60 | x[i] = '1'; 61 | y[i] = '0'; 62 | } 63 | no[i] = '0'; 64 | } 65 | } 66 | int m = l + r >> 1; 67 | kill(n, l, m, y); 68 | kill(n, m, r, x); 69 | } 70 | 71 | vector restore_permutation (int n, int w, int r) { 72 | go(n, 0, n); 73 | compile_set(); 74 | v.resize(n); 75 | string s = ""; 76 | for (int i = 0; i < n; ++i) { 77 | s += '0'; 78 | } 79 | kill(n, 0, n, s); 80 | return v; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /LightOJ 1002.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1002 - Country Roads 9 | 10 | Category: Graph Theory, Shortest Path 11 | 12 | Keys: Modified Dijkstra 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | struct node {int label, dist;}; 32 | 33 | vector Graph[505]; 34 | int T, n, m, u, v, w, t, i, k; 35 | 36 | void Read (void) { 37 | for (i = 0; i < 503; i++) Graph[i].clear(); 38 | scanf("%d %d", &n, &m); node N; 39 | while (m--) { 40 | scanf("%d %d %d", &u, &v, &w); 41 | N.label = u, N.dist = w; 42 | Graph[v].push_back(N); 43 | N.label = v; 44 | Graph[u].push_back(N); 45 | } 46 | scanf("%d", &t); 47 | } 48 | 49 | vector Mod_Dijkstra (void) { 50 | vector Q, Dist(505); 51 | for (i = 0; i < n; i++) 52 | Dist[i] = inf, Q.push_back(i); 53 | Dist[t] = 0; int V, Val, s; 54 | while (!Q.empty()) { 55 | V = 0, Val = inf; 56 | for (i = 0; i < Q.size(); i++) 57 | if (Dist[Q[i]] <= Val) V = Q[i], Val = Dist[Q[i]]; 58 | Q.erase(remove(Q.begin(), Q.end(), V), Q.end()); 59 | for (s = 0; s < Graph[V].size(); s++) { 60 | node vertex = Graph[V][s]; 61 | int alt = max(Dist[V], vertex.dist); 62 | Dist[vertex.label] = min(alt, Dist[vertex.label]); 63 | } 64 | } 65 | return Dist; 66 | } 67 | 68 | void Kill (void) { 69 | scanf("%d", &T); 70 | for (k = 1; k <= T; k++) { 71 | Read(); printf("Case %d:\n", k); 72 | vector Ret = Mod_Dijkstra(); 73 | for (i = 0; i < n; i++) { 74 | if (Ret[i] == inf) printf("Impossible\n"); 75 | else printf("%d\n", Ret[i]); 76 | } 77 | } 78 | } 79 | 80 | int main () { 81 | Kill(); 82 | return 0; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /LightOJ 1035.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1035 - Intelligent Factorial Factorization 9 | 10 | Category: Number Theory, Implementation 11 | 12 | Keys: Legendre's Formula, Sieve of Eratosthenes 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | int T, N, i, j, k, cnt, e, p; 32 | vector primes; bool mark[150]; 33 | 34 | void sieve (void) { 35 | memset(mark, true, sizeof mark); 36 | for (i = 2; i < 120; i++) 37 | for (j = i * i; j < 120; j += i) 38 | mark[j] = false; 39 | for (i = 2; i < 120; i++) 40 | if (mark[i]) primes.push_back(i); 41 | } 42 | 43 | void Kill (void) { 44 | sieve(); scanf("%d", &T); 45 | for (k = 1; k <= T; k++) { 46 | scanf("%d", &N); cnt = 0; 47 | printf("Case %d: %d = ", k, N); 48 | for (i = 0; i < primes.size(); i++) { 49 | p = primes[i], e = 0; 50 | if (p > N) break; 51 | double tmp = N * 1.0; 52 | while (tmp >= 1) 53 | tmp /= (p * 1.0), e += floor(tmp); 54 | if (cnt++ != 0) printf(" * "); 55 | printf("%d (%d)", p, e); 56 | } 57 | printf("\n"); 58 | } 59 | } 60 | 61 | int main () { 62 | Kill(); 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /LightOJ 1062.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1062 - Crossed Ladders 9 | 10 | Category: Computational Geometry 11 | 12 | Keys: Similar Triangles, Binary Search 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | double x, y, c, d, lo, hi, p, q, cmp; 32 | 33 | void Kill (void) { 34 | int T, k; scanf("%d", &T); 35 | for (k = 1; k <= T; k++) { 36 | scanf("%lf %lf %lf", &x, &y, &c); 37 | lo = 0, hi = min(x, y); 38 | while (lo < hi) { 39 | d = (lo + hi)/2; 40 | p = sqrt(x * x - d * d), q = sqrt(y * y - d * d); 41 | cmp = (p * q)/(p + q); 42 | if (abs(cmp - c) <= eps) break; 43 | else if (cmp > c) lo = d; 44 | else hi = d; 45 | } 46 | printf("Case %d: %lf\n", k, d); 47 | } 48 | } 49 | 50 | int main () { 51 | Kill(); 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /LightOJ 1065.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1065 - Number Sequence 9 | 10 | Category - Mathematics, Linear Algebra 11 | 12 | Keys: Matrix Exponentiation, Big Mod 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | i64 T, a, b, n, m, k, Result[3][3], Val; 32 | 33 | void Mat_Mult (i64 A[][3], i64 B[][3], i64 Prod[][3]) { 34 | Prod[0][0] = (A[0][0] * B[0][0] + A[0][1] * B[1][0]) % m; 35 | Prod[0][1] = (A[0][0] * B[0][1] + A[0][1] * B[1][1]) % m; 36 | Prod[1][0] = (A[1][0] * B[0][0] + A[1][1] * B[1][0]) % m; 37 | Prod[1][1] = (A[1][0] * B[0][1] + A[1][1] * B[1][1]) % m; 38 | } 39 | 40 | void Mat_Exp (i64 X[][3], i64 Ret[][3], i64 n) { 41 | i64 Temp[3][3]; 42 | Ret[0][0] = 1, Ret[0][1] = 0; 43 | Ret[1][0] = 0, Ret[1][1] = 1; 44 | while (n) { 45 | if (n & 1) { 46 | Mat_Mult(Ret, X, Temp); 47 | Ret[0][0] = Temp[0][0], Ret[0][1] = Temp[0][1]; 48 | Ret[1][0] = Temp[1][0], Ret[1][1] = Temp[1][1]; 49 | } 50 | Mat_Mult(X, X, Temp); 51 | X[0][0] = Temp[0][0], X[0][1] = Temp[0][1]; 52 | X[1][0] = Temp[1][0], X[1][1] = Temp[1][1]; 53 | n = n >> 1; 54 | } return; 55 | } 56 | 57 | void Kill (void) { 58 | scanf("%lld", &T); 59 | for (k = 1; k <= T; k++) { 60 | scanf("%lld %lld %lld %lld", &a, &b, &n, &m); 61 | m = pow(10, m); 62 | printf("Case %lld: ", k); 63 | if (n == 0) printf("%lld\n", a); 64 | else if (n == 1) printf("%lld\n", b); 65 | else { 66 | i64 Base[3][3] = {{1, 1}, {1, 0}}; 67 | Mat_Exp(Base, Result, n); 68 | Val = b * Result[1][0] + a * Result[1][1]; 69 | printf("%lld\n", Val % m); 70 | } 71 | } 72 | } 73 | 74 | int main () { 75 | Kill(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /LightOJ 1093.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1093 - Ghajini 9 | 10 | Category: Ad hoc, Data Structure 11 | 12 | Keys: Sliding Window, Range Min/Max Query 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | struct elem {int val, idx;}; 32 | 33 | deque DQ; 34 | vector V, Min, Max; 35 | int T, n, d, i, k, tmp, ret; 36 | 37 | void Find_Min (void) { 38 | Min.clear(), DQ.clear(); 39 | for (i = 0; i < n; i++) { 40 | while (!DQ.empty() && DQ.front().val >= V[i]) DQ.pop_front(); 41 | elem E; E.val = V[i], E.idx = i; DQ.push_front(E); 42 | while (!DQ.empty() && DQ.back().idx <= i - d) DQ.pop_back(); 43 | if (i >= d - 1) Min.push_back(DQ.back().val); 44 | } 45 | } 46 | 47 | void Find_Max (void) { 48 | Max.clear(), DQ.clear(); 49 | for (i = 0; i < n; i++) { 50 | while (!DQ.empty() && DQ.front().val <= V[i]) DQ.pop_front(); 51 | elem E; E.val = V[i], E.idx = i; DQ.push_front(E); 52 | while (!DQ.empty() && DQ.back().idx <= i - d) DQ.pop_back(); 53 | if (i >= d - 1) Max.push_back(DQ.back().val); 54 | } 55 | } 56 | 57 | void Kill (void) { 58 | scanf("%d", &T); 59 | for (k = 1; k <= T; k++) { 60 | V.clear(); scanf("%d %d", &n, &d); 61 | for (i = 0; i < n; i++) scanf("%d", &tmp), V.push_back(tmp); 62 | Find_Min(), Find_Max(); ret = 0; 63 | for (i = 0; i < n - d + 1; i++) ret = max(ret, Max[i] - Min[i]); 64 | printf("Case %d: %d\n", k, ret); 65 | } 66 | } 67 | 68 | int main () { 69 | Kill(); 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /LightOJ 1098.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1098 - A New Function 9 | 10 | Category: Mathematics, Number Theory 11 | 12 | Keys: Observation, Counting 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | i64 CSOD (i64 n) { 32 | i64 s, t, sq = floor(sqrt(n)), ret = 0; 33 | for (s = 2; s <= sq; s++) 34 | t = n / s, 35 | ret += s * (t - s + 1) + t * (t + 1)/2 - s * (s + 1)/2; 36 | return ret; 37 | } 38 | 39 | void Kill (void) { 40 | i64 T, N, k; scanf("%lld", &T); 41 | for (k = 1; k <= T; k++) 42 | scanf("%lld", &N), 43 | printf("Case %lld: %lld\n", k, CSOD(N)); 44 | } 45 | 46 | int main () { 47 | Kill(); 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /LightOJ 1186.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1186 - Incredible Chess 9 | 10 | Category: Game Theory 11 | 12 | Keys: Nim Transformation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 100000007 30 | #define MAX 105 31 | 32 | int T, Nim_Sum, A[MAX], n, i, Num, cs = 1; 33 | 34 | int main() { 35 | scanf("%d", &T); while (T--) { 36 | scanf("%d", &n); Nim_Sum = 0; 37 | for (i = 1; i <= n; i++) scanf("%d", A + i); 38 | for (i = 1; i <= n; i++) { 39 | scanf("%d", &Num); 40 | Nim_Sum ^= (Num - A[i] - 1); 41 | } 42 | printf("Case %d: %s wins\n", cs++, Nim_Sum ? "white" : "black"); 43 | } 44 | return 0; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /LightOJ 1192.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1192 - Left Right 9 | 10 | Category: Game Theory 11 | 12 | Keys: Nim Transformation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 100000007 30 | 31 | int T, Nim_Sum, k, i, a, b, cs = 1; 32 | 33 | int main() { 34 | scanf("%d", &T); while (T--) { 35 | scanf("%d", &k); Nim_Sum = 0; 36 | for (i = 1; i <= k; i++) { 37 | scanf("%d %d", &a, &b); 38 | Nim_Sum ^= (b - a - 1); 39 | } 40 | printf("Case %d: %s\n", cs++, Nim_Sum ? "Alice" : "Bob"); 41 | } 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /LightOJ 1234.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1234 - Harmonic Number 9 | 10 | Category: Mathematics, Number Theory 11 | 12 | Keys: Asymptotic Expansion 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | #define MAX 10000 32 | #define gamma 0.5772156649 // Euler-Mascheroni constant 33 | 34 | int T, n, j, k; double H[MAX + 5], bernouli; 35 | 36 | void Fill (void) { 37 | H[1] = 1; 38 | for (j = 2; j <= MAX; j++) H[j] = H[j - 1] + 1/(1.0 * j); 39 | } 40 | 41 | void Kill (void) { 42 | scanf("%d", &T); 43 | for (k = 1; k <= T; k++) { 44 | scanf("%d", &n), printf("Case %d: ", k); 45 | bernouli = 1/(2.0 * n) - 1/(12.0 * n * n) + 1/(120.0 * n * n * n * n); 46 | if (n <= MAX) printf("%0.10lf\n", H[n]); 47 | else printf("%0.10lf\n", log(n) + gamma + bernouli); 48 | } 49 | } 50 | 51 | int main () { 52 | Fill(), Kill(); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /LightOJ 1247.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1247 - Matrix Game 9 | 10 | Category: Game Theory 11 | 12 | Keys: Nim Transformation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 100000007 30 | 31 | int T, Nim_Sum, i, j, Row, Num, m, n, cs = 1; 32 | 33 | int main() { 34 | scanf("%d", &T); while (T--) { 35 | scanf("%d %d", &m, &n); Nim_Sum = 0; 36 | for (i = 1; i <= m; i++) { 37 | Row = 0; 38 | for (j = 1; j <= n; j++) { 39 | scanf("%d", &Num); 40 | Row += Num; 41 | } 42 | Nim_Sum ^= Row; 43 | } 44 | printf("Case %d: %s\n", cs++, Nim_Sum ? "Alice" : "Bob"); 45 | } 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /LightOJ 1253.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1253 - Misere Nim 9 | 10 | Category: Game Theory 11 | 12 | Keys: Sprague Grundy Numbers 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 100000007 30 | 31 | int T, Sum, i, Num, k, Not_One, cs = 1; 32 | 33 | int main() { 34 | scanf("%d", &T); while (T--) { 35 | scanf("%d", &k); 36 | Sum = 0, Not_One = 0; 37 | for (i = 1; i <= k; i++) { 38 | scanf("%d", &Num); 39 | if (Num > 1) ++Not_One; 40 | Sum ^= Num; 41 | } 42 | printf("Case %d: %s\n", cs++, Not_One ? Sum ? "Alice" : "Bob" : Sum ? "Bob" : "Alice"); 43 | } 44 | return 0; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /LightOJ 1259.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1259 - Goldbach's Conjecture 9 | 10 | Category - Mathematics, Number Theory 11 | 12 | Keys: Sieve of Eratosthenes 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX 10000000 31 | 32 | vector primes; bool Mark[MAX]; 33 | 34 | void Sieve (void) { 35 | memset(Mark, true, sizeof Mark); 36 | int i, j; Mark[1] = false; 37 | for (i = 2; i * i <= MAX; i++) 38 | if (Mark[i]) 39 | for (j = i * i; j <= MAX; j += i) 40 | Mark[j] = false; 41 | for (i = 2; i <= MAX; i++) 42 | if (Mark[i]) primes.push_back(i); 43 | } 44 | 45 | void Kill (void) { 46 | int T, k, n, t, lim, ret; Sieve(); 47 | lim = primes.size(); scanf("%d", &T); 48 | for (k = 1; k <= T; k++) { 49 | scanf("%d", &n); ret = 0; 50 | for (t = 0; t < lim && primes[t] <= n/2; t++) 51 | if (Mark[n - primes[t]]) ret++; 52 | printf("Case %d: %d\n", k, ret); 53 | } 54 | } 55 | 56 | int main () { 57 | Kill(); 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /LightOJ 1307.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1035 - Intelligent Factorial Factorization 9 | 10 | Category: Number Theory, Implementation 11 | 12 | Keys: Legendre's Formula, Sieve of Eratosthenes 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | vector V; 32 | int T, N, i, j, k, t, ret; 33 | 34 | void Kill (void) { 35 | scanf("%d", &T); 36 | for (k = 1; k <= T; k++) { 37 | scanf("%d", &N), ret = 0, V.clear(); 38 | for (j = 0; j < N; j++) scanf("%d", &t), V.push_back(t); 39 | sort(V.begin(), V.end()); 40 | for (i = 0; i < N; i++) { 41 | for (j = i + 1; j < N; j++) { 42 | t = lower_bound(V.begin(), V.end(), V[i] + V[j]) - V.begin(); 43 | ret += (t - j - 1); 44 | } 45 | } 46 | printf("Case %d: %d\n", k, ret); 47 | } 48 | } 49 | 50 | int main () { 51 | Kill(); 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /LightOJ 1392.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | LightOJ 1392 - Multi Round Matches 9 | 10 | Category: Mathematics 11 | 12 | Keys: Inequality, Bounding, Algebraic Manipulation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | int Test, Case = 0; 21 | long long R, T, N; 22 | 23 | long long Sum (long long l, long long r) { 24 | if (l > r) return 0; 25 | long long a = (r * (r + 1)) >> 1; 26 | long long b = (l * (l - 1)) >> 1; 27 | return a - b; 28 | } 29 | 30 | int main (int argc, char const *argv[]) { 31 | scanf("%d", &Test); while (Test--) { 32 | scanf("%lld %lld %lld", &R, &T, &N); 33 | printf("Case %d: ", ++Case); 34 | 35 | if (T < R or T > N * R) { 36 | printf("0\n"); 37 | continue; 38 | } 39 | 40 | long long low = (N * R - T + N - 2)/(N - 1); 41 | long long high = (T - R)/(N - 1); 42 | 43 | long long X = N * Sum(1, min(R - 1, high)) + max(0LL, R - high - 1) * (T - R) + Sum(high + 1, R - 1); 44 | long long Y = Sum(1, min(low - 1, R - 1)) - max(0LL, R - low) * (N * R - T) + N * Sum(low, R - 1); 45 | long long Answer = X - Y + R - 1; 46 | 47 | printf("%lld\n", Answer); 48 | } 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /NCPC 2015 - Farey Sequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | NCPC 2015 - Farey Sequence (UVa 12995) 9 | 10 | Category: Mathematics 11 | 12 | Keys: Observation, Number Theory 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e6 + 10; 21 | 22 | int t, n; 23 | long long phiSum[N]; 24 | 25 | void generate_totient (void) { 26 | for (int i = 2; i < N; ++i) { 27 | phiSum[i] = i; 28 | } 29 | for (int i = 2; i < N; ++i) { 30 | if (phiSum[i] == i) { 31 | for (int j = i; j < N; j += i) { 32 | phiSum[j] /= i; 33 | phiSum[j] *= (i - 1); 34 | } 35 | } 36 | } 37 | for (int i = 1; i < N; ++i) { 38 | if (phiSum[i] == i) --phiSum[i]; 39 | phiSum[i] += phiSum[i - 1]; 40 | } 41 | } 42 | 43 | int main (int argc, char const *argv[]) { 44 | generate_totient(); 45 | while (scanf("%d", &n) and n) { 46 | printf("%lld\n", phiSum[n]); 47 | } 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /NCPC 2015 - Palindromic Bases.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | NCPC 2015 - Palindromic Bases (UVa 12994) 9 | 10 | Category: Mathematics 11 | 12 | Keys: Prime Factorization, Backtracking 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long ll; 21 | typedef pair pii; 22 | 23 | const int M = 70; 24 | const int N = 1e7 + 10; 25 | 26 | int t, cs = 0; 27 | bitset vis; 28 | ll n, m, tmp[M]; 29 | int size, tot, res; 30 | vector primes; 31 | vector factors; 32 | 33 | void sieve (void) { 34 | for (int i = 2; i * i < N; ++i) if (!vis[i]) { 35 | for (int j = i * i; j < N; j += i) vis[j] = 1; 36 | } 37 | for (int i = 2; i < N; ++i) { 38 | if (!vis[i]) primes.push_back((ll) i); 39 | } 40 | size = primes.size(); 41 | } 42 | 43 | bool check (ll x, ll base) { 44 | if (base < 2) return false; 45 | int l = 0; 46 | while (x) { 47 | tmp[++l] = x % base; 48 | x /= base; 49 | } 50 | if (l & 1) return false; 51 | for (int i = 1, j = l; i < j; ++i, --j) { 52 | if (tmp[i] != tmp[j]) return false; 53 | } 54 | return true; 55 | } 56 | 57 | void backtrack (int pos, ll d) { 58 | if (pos == tot) { 59 | if (check(m, d - 1)) ++res; 60 | return; 61 | } 62 | for (int j = 0; j <= factors[pos].second; ++j) { 63 | backtrack(pos + 1, d); 64 | d *= factors[pos].first; 65 | } 66 | } 67 | 68 | int main (int argc, char const *argv[]) { 69 | sieve(); 70 | scanf("%d", &t); while (t--) { 71 | scanf("%lld", &n); 72 | m = n, res = 0; 73 | for (int i = 0; i < size; ++i) { 74 | if (primes[i] * primes[i] > n) break; 75 | int e = 0; 76 | while (n % primes[i] == 0) ++e, n /= primes[i]; 77 | factors.push_back(pii(primes[i], e)); 78 | } 79 | if (n > 1) factors.push_back(pii(n, 1)); 80 | tot = factors.size(); 81 | backtrack(0, 1); 82 | factors.clear(); 83 | printf("Case %d: %d\n", ++cs, res); 84 | } 85 | return 0; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /NCPC 2015 - Train Station.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | NCPC 2015 - Train Station (UVa 12997) 9 | 10 | Category: Mathematics 11 | 12 | Keys: Calculus, Numerical Integration 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int MAGIC = 1000; 21 | const long double EPS = 1e-10; 22 | 23 | int t, cs = 0; 24 | long double x, a, b, d; 25 | 26 | long double at (long double p) { 27 | long double one = hypot(p, x); 28 | long double two = hypot(p + d, x); 29 | long double ret = one * two + d * (one + two) - one * one - p * d; 30 | return ret/2.0; 31 | } 32 | 33 | int main (int argc, char const *argv[]) { 34 | scanf("%d", &t); while (t--) { 35 | scanf("%Lf %Lf %Lf %Lf", &x, &a, &b, &d); 36 | a -= d; 37 | printf("Case %d: ", ++cs); 38 | if (fabs(a - b) < EPS) { 39 | long double ans = at(b)/d; 40 | printf("%0.12f\n", (double) ans); 41 | continue; 42 | } 43 | long double jump = (a - b)/MAGIC; 44 | long double ans = (at(a) + at(b))/2.0; 45 | for (int k = 1; k < MAGIC; ++k) { 46 | ans += at(b + k * jump); 47 | } 48 | ans *= jump, ans /= d, ans /= (a - b); 49 | printf("%0.12f\n", (double) ans); 50 | } 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CoolestCodeLibrary 2 | Solutions to some of the programming problems I've solved. 3 | -------------------------------------------------------------------------------- /RUET IUPC 2019 - Balloon Heads.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int H = 5; 6 | const int N = 200010; 7 | const int M = 400010; 8 | 9 | tuple events[M]; 10 | vector indices[H], y_coord[H]; 11 | tuple queries[H][N]; 12 | int tests, cs, n, q, h, t, x[N], y[N], ans[N], where[N], f[M], sz[H]; 13 | 14 | void update (int p, int v) { 15 | while (p < M) f[p] += v, p += p & -p; 16 | } 17 | 18 | void range (int l, int r, int v) { 19 | update(l, v); update(r + 1, -v); 20 | } 21 | 22 | int get (int p) { 23 | int ret = 0; 24 | while (p) ret += f[p], p -= p & -p; 25 | return ret; 26 | } 27 | 28 | void solve (int rem, int l, int r) { 29 | if (l >= r) return; 30 | int mid = l + r >> 1, tot = 0; 31 | for (int i = l; i <= mid; ++i) { 32 | auto [l, r, y_l, y_r] = queries[rem][i]; 33 | if (y_l == -1) continue; 34 | events[tot++] = make_tuple(l, -1, i); 35 | events[tot++] = make_tuple(r, +1, i); 36 | } 37 | for (int i = mid + 1; i <= r; ++i) { 38 | auto [pos, id, y_l, y_r] = queries[rem][i]; 39 | if (y_l != -1) continue; 40 | events[tot++] = make_tuple(where[pos], 0, i); 41 | } 42 | sort(events, events + tot); 43 | for (int i = 0; i < tot; ++i) { 44 | auto [x_at, type, idx] = events[i]; 45 | if (type == -1) { 46 | auto [l, r, y_l, y_r] = queries[rem][idx]; 47 | range(y_l, y_r, +1); 48 | } else if (type == +1) { 49 | auto [l, r, y_l, y_r] = queries[rem][idx]; 50 | range(y_l, y_r, -1); 51 | } else { 52 | auto [pos, id, y_l, y_r] = queries[rem][idx]; 53 | ans[id] += get(y[pos]); 54 | } 55 | } 56 | solve(rem, l, mid); solve(rem, mid + 1, r); 57 | } 58 | 59 | int main() { 60 | cin >> tests; 61 | while (tests--) { 62 | cin >> n >> q >> h >> t; 63 | int s_x, s_y, t_x, t_y, lim; 64 | cin >> s_x >> s_y >> t_x >> t_y >> lim; 65 | int at = 1, seed = s_x; 66 | auto advance = [] (int &seed) { 67 | seed = (seed * 1103515245LL + 1234) % 100000001; 68 | }; 69 | while (at <= n) { 70 | x[at] = s_x + seed % (t_x - s_x + 1), advance(seed); 71 | y[at] = s_y + seed % (t_y - s_y + 1), advance(seed); 72 | if (y[at] % h) ++at; 73 | } 74 | for (int rem = 1; rem < h; ++rem) indices[rem].clear(), y_coord[rem].clear(), sz[rem] = 0; 75 | for (int i = 1; i <= n; ++i) indices[y[i] % h].emplace_back(i); 76 | for (int rem = 1; rem < h; ++rem) { 77 | if (indices[rem].empty()) continue; 78 | sort(indices[rem].begin(), indices[rem].end(), [] (int i, int j) { 79 | return x[i] < x[j]; 80 | }); 81 | for (int i = 0; i < indices[rem].size(); ++i) where[indices[rem][i]] = i; 82 | } 83 | int ptr = 0; 84 | while (q--) { 85 | int cmd, val; 86 | scanf("%d %d", &cmd, &val); 87 | if (cmd == 1) { 88 | int x_l, y_l, x_r, y_r, seed = val; 89 | advance(seed), x_l = 1 + seed % lim; 90 | advance(seed), y_l = 1 + seed % lim; 91 | advance(seed), x_r = 100000000 - seed % lim; 92 | advance(seed), y_r = 100000000 - seed % lim; 93 | x_r += x_l, y_r += y_l; 94 | for (int rem = 1; rem < h; ++rem) { 95 | if (indices[rem].empty()) continue; 96 | int l = lower_bound(indices[rem].begin(), indices[rem].end(), x_l, [] (int i, int j) { 97 | return x[i] < j; 98 | }) - indices[rem].begin(); 99 | int r = upper_bound(indices[rem].begin(), indices[rem].end(), x_r, [] (int i, int j) { 100 | return i < x[j]; 101 | }) - indices[rem].begin() - 1; 102 | if (l > r) continue; 103 | int passed = val + rem + t, added = passed / (t + h) * h; 104 | passed %= t + h; if (passed > t) added += passed - t; 105 | y_l += rem - added, y_r += rem - added; 106 | queries[rem][sz[rem]++] = make_tuple(l, r, y_l, y_r); 107 | y_coord[rem].emplace_back(y_l), y_coord[rem].emplace_back(y_r); 108 | y_l -= rem - added, y_r -= rem - added; 109 | } 110 | } else { 111 | int rem = y[val] % h; ans[ptr] = 0; 112 | queries[rem][sz[rem]++] = make_tuple(val, ptr++, -1, -1); 113 | y_coord[rem].emplace_back(y[val]); 114 | } 115 | } 116 | for (int rem = 1; rem < h; ++rem) { 117 | if (y_coord[rem].empty()) continue; 118 | sort(y_coord[rem].begin(), y_coord[rem].end()); 119 | y_coord[rem].erase(unique(y_coord[rem].begin(), y_coord[rem].end()), y_coord[rem].end()); 120 | for (int i = 0; i < sz[rem]; ++i) { 121 | auto &[l, r, y_l, y_r] = queries[rem][i]; 122 | if (y_l == -1) continue; 123 | y_l = lower_bound(y_coord[rem].begin(), y_coord[rem].end(), y_l) - y_coord[rem].begin() + 1; 124 | y_r = lower_bound(y_coord[rem].begin(), y_coord[rem].end(), y_r) - y_coord[rem].begin() + 1; 125 | } 126 | } 127 | for (int i = 1; i <= n; ++i) { 128 | int rem = y[i] % h; 129 | y[i] = lower_bound(y_coord[rem].begin(), y_coord[rem].end(), y[i]) - y_coord[rem].begin() + 1; 130 | } 131 | for (int rem = 1; rem < h; ++rem) { 132 | if (sz[rem]) solve(rem, 0, sz[rem] - 1); 133 | } 134 | printf("Case %d:\n", ++cs); 135 | for (int i = 0; i < ptr; ++i) printf("%d\n", ans[i]); 136 | } 137 | return 0; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /SGU 507.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SGU 507 - Treediff 9 | 10 | Category: Graph Theory 11 | 12 | Keys: DSU on Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 50010; 21 | const int INF = int((1LL << 31) - 1LL); 22 | 23 | vector g[N]; 24 | int n, m, w[N], ans[N]; 25 | 26 | void dfs (int u, set &f) { 27 | ans[u] = INF; 28 | if (u > n - m) { 29 | f.insert(w[u]); 30 | return; 31 | } 32 | for (int v : g[u]) { 33 | set t; 34 | dfs(v, t); 35 | ans[u] = min(ans[u], ans[v]); 36 | if (t.size() > f.size()) f.swap(t); 37 | for (int x : t) { 38 | if (ans[u] > 0) { 39 | if (f.count(x)) { 40 | ans[u] = 0; 41 | } 42 | } 43 | f.insert(x); 44 | if (ans[u] == 0) { 45 | continue; 46 | } 47 | auto it = f.find(x); 48 | if (it != f.begin()) { 49 | auto other = it; 50 | --other; 51 | ans[u] = min(ans[u], abs(*it - *other)); 52 | } 53 | if (it != --f.end()) { 54 | auto other = it; 55 | ++other; 56 | ans[u] = min(ans[u], abs(*it - *other)); 57 | } 58 | } 59 | } 60 | } 61 | 62 | int main() { 63 | scanf("%d %d", &n, &m); 64 | for (int i = 2; i <= n; ++i) { 65 | int par; 66 | scanf("%d", &par); 67 | g[par].push_back(i); 68 | } 69 | for (int i = 1; i <= m; ++i) { 70 | scanf("%d", w + n - m + i); 71 | } 72 | set f; 73 | dfs(1, f); 74 | for (int i = 1; i <= n - m; ++i) { 75 | printf("%d ", ans[i]); 76 | } 77 | puts(""); 78 | return 0; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /SPOJ - Can you answer these queries I.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Can you answer these queries I (GSS1) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 5e4 + 10; 21 | const int INF = 1e9 + 10; 22 | 23 | struct node { 24 | int pre, suf, sum, best; 25 | node () {} 26 | node (int a, int b, int c, int d) : pre(a), suf(b), sum(c), best(d) {} 27 | }; 28 | 29 | node t[4 * N]; 30 | int n, m, a[N]; 31 | 32 | node merge (node a, node b) { 33 | node c; 34 | c.sum = a.sum + b.sum; 35 | c.pre = max(a.pre, a.sum + b.pre); 36 | c.suf = max(b.suf, b.sum + a.suf); 37 | c.best = max(max(a.best, b.best), a.suf + b.pre); 38 | return c; 39 | } 40 | 41 | void build (int u, int b, int e) { 42 | if (b == e) { 43 | t[u] = node(a[b], a[b], a[b], a[b]); 44 | return; 45 | } 46 | 47 | int l = u << 1, r = l + 1, m = b + e >> 1; 48 | build(l, b, m), build(r, m + 1, e); 49 | t[u] = merge(t[l], t[r]); 50 | } 51 | 52 | node query (int u, int b, int e, int p, int q) { 53 | if (b > q or e < p) return node(-INF, -INF, 0, -INF); 54 | if (b >= p and e <= q) return t[u]; 55 | 56 | int l = u << 1, r = l + 1, m = b + e >> 1; 57 | node qleft = query(l, b, m, p, q), qright = query(r, m + 1, e, p, q); 58 | return merge(qleft, qright); 59 | } 60 | 61 | int main (int argc, char const *argv[]) { 62 | scanf("%d", &n); 63 | for (int i = 1; i <= n; ++i) scanf("%d", a + i); 64 | build(1, 1, n); 65 | 66 | scanf("%d", &m); while (m--) { 67 | int x, y; 68 | scanf("%d %d", &x, &y); 69 | printf("%d\n", query(1, 1, n, x, y).best); 70 | } 71 | 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /SPOJ - Can you answer these queries III.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Can you answer these queries III (GSS3) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 5e4 + 10; 21 | const int INF = 1e9 + 10; 22 | 23 | struct node { 24 | int pre, suf, sum, best; 25 | node () {} 26 | node (int a, int b, int c, int d) : pre(a), suf(b), sum(c), best(d) {} 27 | }; 28 | 29 | node t[4 * N]; 30 | int n, m, a[N]; 31 | 32 | node merge (node a, node b) { 33 | node c; 34 | c.sum = a.sum + b.sum; 35 | c.pre = max(a.pre, a.sum + b.pre); 36 | c.suf = max(b.suf, b.sum + a.suf); 37 | c.best = max(max(a.best, b.best), a.suf + b.pre); 38 | return c; 39 | } 40 | 41 | void build (int u, int b, int e) { 42 | if (b == e) { 43 | t[u] = node(a[b], a[b], a[b], a[b]); 44 | return; 45 | } 46 | 47 | int l = u << 1, r = l | 1, m = b + e >> 1; 48 | build(l, b, m), build(r, m + 1, e); 49 | t[u] = merge(t[l], t[r]); 50 | } 51 | 52 | void update (int u, int b, int e, int p, int v) { 53 | if (b > p or e < p) return; 54 | if (b == e) { 55 | t[u] = node(v, v, v, v); 56 | return; 57 | } 58 | 59 | int l = u << 1, r = l | 1, m = b + e >> 1; 60 | update(l, b, m, p, v), update(r, m + 1, e, p, v); 61 | t[u] = merge(t[l], t[r]); 62 | } 63 | 64 | node query (int u, int b, int e, int p, int q) { 65 | if (b > q or e < p) return node(-INF, -INF, 0, -INF); 66 | if (b >= p and e <= q) return t[u]; 67 | 68 | int l = u << 1, r = l | 1, m = b + e >> 1; 69 | node qleft = query(l, b, m, p, q), qright = query(r, m + 1, e, p, q); 70 | return merge(qleft, qright); 71 | } 72 | 73 | int main (int argc, char const *argv[]) { 74 | scanf("%d", &n); 75 | for (int i = 1; i <= n; ++i) scanf("%d", a + i); 76 | build(1, 1, n); 77 | 78 | scanf("%d", &m); while (m--) { 79 | int cmd, x, y; 80 | scanf("%d %d %d", &cmd, &x, &y); 81 | 82 | if (cmd) printf("%d\n", query(1, 1, n, x, y).best); 83 | else update(1, 1, n, x, y); 84 | } 85 | 86 | return 0; 87 | } 88 | 89 | -------------------------------------------------------------------------------- /SPOJ - Can you answer these queries IV.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Can you answer these queries IV (GSS4) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree, Ad-hoc Optimization, Observation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e5 + 10; 21 | 22 | int n, m, cs = 0; 23 | long long a[N], t[4 * N]; 24 | 25 | void build (int u, int b, int e) { 26 | if (b == e) { 27 | t[u] = a[b]; 28 | return; 29 | } 30 | 31 | int l = u << 1, r = l | 1, m = b + e >> 1; 32 | build(l, b, m), build(r, m + 1, e); 33 | t[u] = t[l] + t[r]; 34 | } 35 | 36 | void update (int u, int b, int e, int p, int q) { 37 | if (t[u] == e - b + 1) return; 38 | if (b > q or e < p) return; 39 | if (b == e) { 40 | t[u] = floor(sqrt(t[u])); 41 | return; 42 | } 43 | 44 | int l = u << 1, r = l | 1, m = b + e >> 1; 45 | update(l, b, m, p, q), update(r, m + 1, e, p, q); 46 | t[u] = t[l] + t[r]; 47 | } 48 | 49 | long long query (int u, int b, int e, int p, int q) { 50 | if (b > q or e < p) return 0; 51 | if (b >= p and e <= q) return t[u]; 52 | 53 | int l = u << 1, r = l | 1, m = b + e >> 1; 54 | return query(l, b, m, p, q) + query(r, m + 1, e, p, q); 55 | } 56 | 57 | int main (int argc, char const *argv[]) { 58 | while (scanf("%d", &n) != EOF) { 59 | for (int i = 1; i <= n; ++i) scanf("%lld", a + i); 60 | memset(t, 0, sizeof t); 61 | build(1, 1, n); 62 | 63 | printf("Case #%d:\n", ++cs); 64 | 65 | scanf("%d", &m); while (m--) { 66 | int cmd, l, r; 67 | scanf("%d %d %d", &cmd, &l, &r); 68 | if (l > r) swap(l, r); 69 | 70 | if (cmd) printf("%lld\n", query(1, 1, n, l, r)); 71 | else update(1, 1, n, l, r); 72 | } 73 | 74 | puts(""); 75 | } 76 | return 0; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /SPOJ - Can you answer these queries V.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Can you answer these queries V (GSS5) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree, Observation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e4 + 10; 21 | const int INF = 1e9 + 10; 22 | 23 | struct node { 24 | int pre, suf, sum, best; 25 | node () {} 26 | node (int a, int b, int c, int d) { 27 | pre = a, suf = b, sum = c, best = d; 28 | } 29 | node operator + (const node &x) const { 30 | node z; 31 | z.pre = max(pre, sum + x.pre); 32 | z.suf = max(x.suf, x.sum + suf); 33 | z.sum = x.sum + sum; 34 | z.best = max(max(x.best, best), suf + x.pre); 35 | return z; 36 | } 37 | }; 38 | 39 | int t, n, m, a[N], sum[N]; 40 | int rangeMin[4 * N], rangeMax[4 * N]; 41 | node rangeMaxSum[4 * N]; 42 | 43 | void init_rmq (int u, int b, int e) { 44 | if (b == e) { 45 | rangeMin[u] = rangeMax[u] = sum[b - 1]; 46 | return; 47 | } 48 | int l = u << 1, r = l | 1, m = b + e >> 1; 49 | init_rmq(l, b, m), init_rmq(r, m + 1, e); 50 | rangeMin[u] = min(rangeMin[l], rangeMin[r]); 51 | rangeMax[u] = max(rangeMax[l], rangeMax[r]); 52 | } 53 | 54 | void init_maxSum (int u, int b, int e) { 55 | if (b == e) { 56 | rangeMaxSum[u] = node(a[b], a[b], a[b], a[b]); 57 | return; 58 | } 59 | int l = u << 1, r = l | 1, m = b + e >> 1; 60 | init_maxSum(l, b, m), init_maxSum(r, m + 1, e); 61 | rangeMaxSum[u] = rangeMaxSum[l] + rangeMaxSum[r]; 62 | } 63 | 64 | int query_rmq (int u, int b, int e, int p, int q, int flag) { 65 | if (b > q or e < p) return flag ? INF : -INF; 66 | if (b >= p and e <= q) return flag ? rangeMin[u] : rangeMax[u]; 67 | int l = u << 1, r = l | 1, m = b + e >> 1; 68 | int left = query_rmq(l, b, m, p, q, flag); 69 | int right = query_rmq(r, m + 1, e, p, q, flag); 70 | return flag ? min(left, right) : max(left, right); 71 | } 72 | 73 | node query_maxSum (int u, int b, int e, int p, int q) { 74 | if (b > q or e < p) return node(-INF, -INF, 0, -INF); 75 | if (b >= p and e <= q) return rangeMaxSum[u]; 76 | int l = u << 1, r = l | 1, m = b + e >> 1; 77 | node left = query_maxSum(l, b, m, p, q); 78 | node right = query_maxSum(r, m + 1, e, p, q); 79 | return left + right; 80 | } 81 | 82 | int solve_disjoint (int w, int x, int y, int z) { 83 | int after = query_rmq(1, 1, n + 1, y + 1, z + 1, 0); 84 | int before = query_rmq(1, 1, n + 1, w, x, 1); 85 | return after - before; 86 | } 87 | 88 | int main (int argc, char const *argv[]) { 89 | scanf("%d", &t); while (t--) { 90 | scanf("%d", &n); 91 | for (int i = 1; i <= n; ++i) { 92 | scanf("%d", a + i); 93 | sum[i] = sum[i - 1] + a[i]; 94 | } 95 | init_rmq(1, 1, n + 1); 96 | init_maxSum(1, 1, n); 97 | scanf("%d", &m); while (m--) { 98 | int w, x, y, z; 99 | scanf("%d %d %d %d", &w, &x, &y, &z); 100 | if (x < y) { 101 | printf("%d\n", solve_disjoint(w, x, y, z)); 102 | } else { 103 | int p = y, q = x; 104 | swap(x, y), --x, ++y; 105 | int one = solve_disjoint(w, x, p, z); 106 | int two = solve_disjoint(w, q, y, z); 107 | int three = query_maxSum(1, 1, n, p, q).best; 108 | int res = max(max(one, two), three); 109 | printf("%d\n", res); 110 | } 111 | } 112 | memset(rangeMin, 0, sizeof rangeMin); 113 | memset(rangeMax, 0, sizeof rangeMax); 114 | memset(rangeMaxSum, 0, sizeof rangeMaxSum); 115 | } 116 | return 0; 117 | } 118 | 119 | -------------------------------------------------------------------------------- /SPOJ - Cost.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Cost (KOICOST) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Union Find, Sorting, Observation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e5 + 10; 21 | const int MOD = 1000000000; 22 | 23 | struct edge { 24 | int u, v; long long w; 25 | bool operator < (const edge &e) const { 26 | return w < e.w; 27 | } 28 | }; 29 | 30 | edge e[N]; 31 | int n, m, p[N]; 32 | long long sum[N], size[N]; 33 | 34 | int find (int x) { 35 | return p[x] == x ? x : p[x] = find(p[x]); 36 | } 37 | 38 | long long merge (int u, int v) { 39 | int x = find(u), y = find(v); 40 | if (x == y) return 0; 41 | 42 | long long ret = (size[x] * size[y]) % MOD; 43 | p[x] = y, size[y] += size[x]; 44 | 45 | return ret; 46 | } 47 | 48 | int main (int argc, char const *argv[]) { 49 | scanf("%d %d", &n, &m); 50 | for (int i = 1; i <= m; ++i) 51 | scanf("%d %d %lld", &e[i].u, &e[i].v, &e[i].w); 52 | 53 | sort(e + 1, e + m + 1); 54 | for (int i = 1; i <= m; ++i) sum[i] = (sum[i - 1] + e[i].w) % MOD; 55 | 56 | for (int i = 1; i <= n; ++i) p[i] = i, size[i] = 1; 57 | 58 | long long res = 0; 59 | for (int i = m; i; --i) res += merge(e[i].u, e[i].v) * sum[i], res %= MOD; 60 | 61 | printf("%lld\n", res); 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /SPOJ - Count on a tree II.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Count on a tree II (COT2) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Tree Flattening, Mo's Algorithm 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | int SQRT; 21 | const int LG = 18; 22 | const int N = 100010; 23 | 24 | struct query { 25 | int id, l, r, lca; 26 | query () {} 27 | query (int a, int b, int c, int d) { 28 | id = a, l = b, r = c, lca = d; 29 | } 30 | bool operator < (const query &q) const { 31 | if (l/SQRT == q.l/SQRT) return r < q.r; 32 | return l/SQRT < q.l/SQRT; 33 | } 34 | }; 35 | 36 | query q[N]; 37 | vector g[N]; 38 | map to; 39 | int n, m, tot, w[N], ans; 40 | int flat[N + N], p[N][LG]; 41 | int l[N], r[N], depth[N]; 42 | int res[N], cnt[N], mark[N]; 43 | 44 | void dfs (int u, int par, int deep) { 45 | p[u][0] = par, depth[u] = deep; 46 | flat[++tot] = u, l[u] = tot; 47 | for (int i = 0; i < (int) g[u].size(); ++i) { 48 | int v = g[u][i]; 49 | if (v == par) continue; 50 | dfs(v, u, deep + 1); 51 | } 52 | flat[++tot] = u, r[u] = tot; 53 | } 54 | 55 | void init (void) { 56 | for (int j = 1; 1 << j <= n; ++j) { 57 | for (int i = 1; i <= n; ++i) { 58 | if (p[i][j - 1] != -1) { 59 | p[i][j] = p[p[i][j - 1]][j - 1]; 60 | } 61 | } 62 | } 63 | } 64 | 65 | int lca (int u, int v) { 66 | if (depth[u] < depth[v]) swap(u, v); 67 | for (int j = LG - 1; j >= 0; --j) { 68 | if (depth[u] - (1 << j) >= depth[v]) { 69 | u = p[u][j]; 70 | } 71 | } 72 | if (u == v) return u; 73 | for (int j = LG - 1; j >= 0; --j) { 74 | if (p[u][j] != -1 and p[u][j] != p[v][j]) { 75 | u = p[u][j], v = p[v][j]; 76 | } 77 | } 78 | return p[u][0]; 79 | } 80 | 81 | void update (int x) { 82 | int u = flat[x]; 83 | if (mark[u] and --cnt[w[u]] == 0) --ans; 84 | if (!mark[u] and cnt[w[u]]++ == 0) ++ans; 85 | mark[u] ^= 1; 86 | } 87 | 88 | int main (int argc, char const *argv[]) { 89 | scanf("%d %d", &n, &m); 90 | for (int i = 1; i <= n; ++i) { 91 | scanf("%d", w + i); 92 | if (!to.count(w[i])) to[w[i]] = ++tot; 93 | w[i] = to[w[i]]; 94 | } 95 | for (int i = 1; i < n; ++i) { 96 | int u, v; 97 | scanf("%d %d", &u, &v); 98 | g[u].push_back(v); 99 | g[v].push_back(u); 100 | } 101 | 102 | memset(p, -1, sizeof p); 103 | tot = 0, dfs(1, 1, 0), init(); 104 | 105 | for (int i = 1; i <= m; ++i) { 106 | int u, v; 107 | scanf("%d %d", &u, &v); 108 | int z = lca(u, v); 109 | if (depth[u] > depth[v]) swap(u, v); 110 | if (z == u) q[i] = query(i, l[u], l[v], 0); 111 | else q[i] = query(i, r[u], l[v], z); 112 | } 113 | 114 | SQRT = sqrt(n); 115 | sort(q + 1, q + m + 1); 116 | 117 | int x = 1, y = 0; 118 | for (int i = 1; i <= m; ++i) { 119 | while (x > q[i].l) update(--x); 120 | while (y < q[i].r) update(++y); 121 | while (x < q[i].l) update(x++); 122 | while (y > q[i].r) update(y--); 123 | 124 | if (q[i].lca) update(l[q[i].lca]); 125 | res[q[i].id] = ans; 126 | if (q[i].lca) update(l[q[i].lca]); 127 | } 128 | 129 | for (int i = 1; i <= m; ++i) { 130 | printf("%d\n", res[i]); 131 | } 132 | return 0; 133 | } 134 | 135 | -------------------------------------------------------------------------------- /SPOJ - DQUERY - O((n + q) sqrt(q) + q lg q).cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - DQUERY - O(q lg q + (n + q) sqrt(q)) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Offline Processing, Square Root Decomposition, Mo's Algorithm 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | int SQRT; 21 | const int N = 1e6 + 10; 22 | 23 | struct query { 24 | int l, r, id; 25 | 26 | query () {} 27 | query (int a, int b, int c) : id(a), l(b), r(c) {} 28 | 29 | bool operator < (const query &q) const { 30 | if (l/SQRT == q.l/SQRT) return r/SQRT < q.r/SQRT; 31 | return l/SQRT < q.l/SQRT; 32 | } 33 | }; 34 | 35 | query x[N]; 36 | int n, q, ans = 0, a[N], res[N], cnt[N]; 37 | 38 | void add (int p) { 39 | if (cnt[a[p]] == 0) ++ans; 40 | ++cnt[a[p]]; 41 | } 42 | 43 | void remove (int p) { 44 | --cnt[a[p]]; 45 | if (cnt[a[p]] == 0) --ans; 46 | } 47 | 48 | int main (int argc, char const *argv[]) { 49 | scanf("%d", &n); 50 | for (int i = 1; i <= n; ++i) scanf("%d", a + i); 51 | 52 | scanf("%d", &q); 53 | for (int i = 1; i <= q; ++i) { 54 | scanf("%d %d", &x[i].l, &x[i].r); 55 | x[i].id = i; 56 | } 57 | 58 | SQRT = sqrt(n); 59 | sort(x + 1, x + q + 1); 60 | 61 | int l = 0, r = 0; 62 | for (int i = 1; i <= q; ++i) { 63 | while (r < x[i].r) add(++r); 64 | while (l > x[i].l) add(--l); 65 | while (l < x[i].l) remove(l++); 66 | while (r > x[i].r) remove(r--); 67 | 68 | res[x[i].id] = ans; 69 | } 70 | 71 | for (int i = 1; i <= q; ++i) printf("%d\n", res[i]); 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /SPOJ - DQUERY - O(n + q lg n).cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - DQUERY - O(n + q lg n) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Offline Processing, Fenwick Tree, Sorting, Two Pointer 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e6 + 10; 21 | 22 | struct query { 23 | int l, r, id; 24 | 25 | query () {} 26 | query (int a, int b, int c) : id(a), l(b), r(c) {} 27 | 28 | bool operator < (const query &q) const { 29 | return r < q.r; 30 | } 31 | }; 32 | 33 | query x[N]; 34 | int n, q, a[N], bit[N], last[N], res[N]; 35 | 36 | void update (int p, int v) { 37 | while (p < N) bit[p] += v, p += (p & -p); 38 | } 39 | 40 | int prefix (int p) { 41 | int sum = 0; 42 | while (p > 0) sum += bit[p], p -= (p & -p); 43 | return sum; 44 | } 45 | 46 | int query (int l, int r) { 47 | return prefix(r) - prefix(l - 1); 48 | } 49 | 50 | int main (int argc, char const *argv[]) { 51 | scanf("%d", &n); 52 | for (int i = 1; i <= n; ++i) scanf("%d", a + i); 53 | 54 | scanf("%d", &q); 55 | for (int i = 1; i <= q; ++i) { 56 | scanf("%d %d", &x[i].l, &x[i].r); 57 | x[i].id = i; 58 | } 59 | 60 | sort(x + 1, x + q + 1); 61 | memset(last, -1, sizeof last); 62 | 63 | for (int i = 1, j = 1; i <= n and j <= q; ++i) { 64 | if (last[a[i]] != -1) update(last[a[i]], -1); 65 | last[a[i]] = i, update(i, 1); 66 | 67 | while (j <= q and x[j].r == i) 68 | res[x[j].id] = query(x[j].l, x[j].r), ++j; 69 | } 70 | 71 | for (int i = 1; i <= q; ++i) printf("%d\n", res[i]); 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /SPOJ - Inversion Count.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Inversion Count (INVCNT) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Fenwick Tree, Sorting 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 2e5 + 10; 21 | 22 | int t, n, bit[N]; 23 | pair p[N]; 24 | 25 | void update (int p, int v) { 26 | while (p < N) bit[p] += v, p += (p & -p); 27 | } 28 | 29 | int query (int p) { 30 | int sum = 0; 31 | while (p > 0) sum += bit[p], p -= (p & -p); 32 | return sum; 33 | } 34 | 35 | int main (int argc, char const *argv[]) { 36 | scanf("%d", &t); while (t--) { 37 | scanf("%d", &n); 38 | for (int i = 1; i <= n; ++i) 39 | scanf("%d", &p[i].first), p[i].second = i; 40 | 41 | sort(p + 1, p + n + 1); 42 | reverse(p + 1, p + n + 1); 43 | 44 | long long tot = 0; 45 | for (int i = 1; i <= n; ++i) { 46 | tot += (long long) query(p[i].second); 47 | update(p[i].second, 1); 48 | } 49 | 50 | printf("%lld\n", tot); 51 | memset(bit, 0, sizeof bit); 52 | } 53 | return 0; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /SPOJ - K-Query II.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - K-Query II (KQUERY2) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Square Root Decomposition, Sorting, Binary Search, Optimizing Constant Factor 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | int BUCKET; 21 | const int N = 30010; 22 | 23 | int n, q; 24 | pair a[N]; 25 | 26 | int main (int argc, char const *argv[]) { 27 | scanf("%d", &n); 28 | for (int i = 1; i <= n; ++i) 29 | scanf("%d", &a[i].first), a[i].second = i; 30 | BUCKET = 2 * sqrt(n); 31 | 32 | for (int i = 1; i <= n; i += BUCKET) 33 | sort(a + i, a + min(n + 1, i + BUCKET)); 34 | 35 | scanf("%d", &q); while (q--) { 36 | int cmd, p, q, x; 37 | scanf("%d", &cmd); 38 | 39 | if (cmd == 0) { 40 | scanf("%d %d", &p, &x); 41 | int start = 1 + BUCKET * ((p - 1)/BUCKET); 42 | 43 | for (int i = start; i <= min(n, start + BUCKET - 1); ++i) 44 | if (a[i].second == p) {a[i].first = x; break;} 45 | 46 | sort(a + start, a + min(n + 1, start + BUCKET)); 47 | } else { 48 | scanf("%d %d %d", &p, &q, &x); 49 | int blockP = (p - 1)/BUCKET, blockQ = (q - 1)/BUCKET, res = 0; 50 | int startP = 1 + BUCKET * blockP, startQ = 1 + BUCKET * blockQ; 51 | 52 | for (int i = startP; i <= min(n, startP + BUCKET - 1); ++i) 53 | if (a[i].second >= p and a[i].second <= q and a[i].first > x) ++res; 54 | 55 | if (blockP != blockQ) { 56 | for (int i = startQ; i <= min(n, startQ + BUCKET - 1); ++i) 57 | if (a[i].second >= p and a[i].second <= q and a[i].first > x) ++res; 58 | 59 | for (int i = blockP + 1; i < blockQ; ++i) { 60 | int start = 1 + BUCKET * i; 61 | int tot = upper_bound(a + start, a + start + BUCKET, make_pair(x, n + 1)) - a - start; 62 | res += max(0, BUCKET - tot); 63 | } 64 | } 65 | 66 | printf("%d\n", res); 67 | } 68 | } 69 | return 0; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /SPOJ - K-Query Online - O(q lg(n) lg(n)).cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - K-Query Online (KQUERYO) - O(q lg(n) lg(n)) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree, Merge Sort, Binary Search 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 30010; 21 | const int INF = 2e9 + 10; 22 | 23 | int n, q, x, res; 24 | vector t[N + N]; 25 | 26 | void merge (int u, int l, int r) { 27 | int L = t[l].size(), R = t[r].size(); 28 | t[l].push_back(INF), t[r].push_back(INF); 29 | 30 | for (int i = 0, j = 0; i < L or j < R;) { 31 | if (t[l][i] < t[r][j]) t[u].push_back(t[l][i++]); 32 | else t[u].push_back(t[r][j++]); 33 | } 34 | 35 | t[l].pop_back(), t[r].pop_back(); 36 | } 37 | 38 | void init (void) { 39 | for (int i = n - 1; i; --i) merge(i, i << 1, i << 1 | 1); 40 | } 41 | 42 | int query (int l, int r, int x) { 43 | int res = 0; 44 | 45 | for (l += n, r += n; l < r; l >>= 1, r >>= 1) { 46 | if (l & 1) { 47 | int pos = upper_bound(t[l].begin(), t[l].end(), x) - t[l].begin(); 48 | res += (int) t[l].size() - pos; 49 | ++l; 50 | } 51 | 52 | if (r & 1) { 53 | --r; 54 | int pos = upper_bound(t[r].begin(), t[r].end(), x) - t[r].begin(); 55 | res += (int) t[r].size() - pos; 56 | } 57 | } 58 | 59 | return res; 60 | } 61 | 62 | int main (int argc, char const *argv[]) { 63 | scanf("%d", &n); 64 | for (int i = 0; i < n; ++i) { 65 | scanf("%d", &x); 66 | t[n + i].push_back(x); 67 | } 68 | 69 | init(); 70 | 71 | scanf("%d", &q); while (q--) { 72 | int l, r, x; 73 | scanf("%d %d %d", &l, &r, &x); 74 | l ^= res, r ^= res, x ^= res; 75 | res = query(max(0, l - 1), min(n, r), x); 76 | printf("%d\n", res); 77 | } 78 | return 0; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /SPOJ - K-Query Online - O(q sqrt(n) lg(n)).cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - K-Query Online (KQUERYO) - O(q sqrt(n) lg(n)) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Square Root Decomposition, Sorting, Binary Search 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | int BUCKET; 21 | const int N = 30010; 22 | 23 | int n, q, res; 24 | pair a[N]; 25 | 26 | int main (int argc, char const *argv[]) { 27 | scanf("%d", &n); 28 | for (int i = 1; i <= n; ++i) 29 | scanf("%d", &a[i].first), a[i].second = i; 30 | BUCKET = sqrt(n); 31 | 32 | for (int i = 1; i <= n; i += BUCKET) 33 | sort(a + i, a + min(n + 1, i + BUCKET)); 34 | 35 | scanf("%d", &q); while (q--) { 36 | int l, r, x; 37 | scanf("%d %d %d", &l, &r, &x); 38 | l ^= res, r ^= res, x ^= res, res = 0; 39 | l = max(l, 1), r = min(r, n); 40 | 41 | int blockL = (l - 1)/BUCKET, blockR = (r - 1)/BUCKET; 42 | int startL = 1 + BUCKET * blockL, startR = 1 + BUCKET * blockR; 43 | 44 | for (int i = startL; i <= min(n, startL + BUCKET - 1); ++i) 45 | if (a[i].second >= l and a[i].second <= r and a[i].first > x) ++res; 46 | 47 | if (blockL != blockR) { 48 | for (int i = startR; i <= min(n, startR + BUCKET - 1); ++i) 49 | if (a[i].second >= l and a[i].second <= r and a[i].first > x) ++res; 50 | 51 | for (int i = blockL + 1; i < blockR; ++i) { 52 | int start = 1 + BUCKET * i; 53 | int tot = upper_bound(a + start, a + start + BUCKET, make_pair(x, n + 1)) - a - start; 54 | res += max(0, BUCKET - tot); 55 | } 56 | } 57 | 58 | printf("%d\n", res); 59 | } 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /SPOJ - K-Query.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - K-Query (KQUERY) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Offline Processing, Fenwick Tree, Pointer Walk, Sorting 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 30010; 21 | const int Q = 2e5 + 10; 22 | 23 | struct query { 24 | int id, l, r, value; 25 | bool operator < (const query &q) const { 26 | return value > q.value; 27 | } 28 | }; 29 | 30 | query x[Q]; 31 | pair a[N]; 32 | int n, q, bit[N], res[Q]; 33 | 34 | void update (int p, int v) { 35 | while (p < N) bit[p] += v, p += (p & -p); 36 | } 37 | 38 | int query (int p) { 39 | int sum = 0; 40 | while (p > 0) sum += bit[p], p -= (p & -p); 41 | return sum; 42 | } 43 | 44 | int main (int argc, char const *argv[]) { 45 | scanf("%d", &n); 46 | for (int i = 1; i <= n; ++i) { 47 | scanf("%d", &a[i].first); 48 | a[i].second = i; 49 | } 50 | 51 | sort(a + 1, a + n + 1); 52 | int pointer = n; 53 | 54 | scanf("%d", &q); 55 | for (int i = 1; i <= q; ++i) { 56 | scanf("%d %d %d", &x[i].l, &x[i].r, &x[i].value); 57 | x[i].id = i; 58 | } 59 | 60 | sort(x + 1, x + q + 1); 61 | 62 | for (int i = 1; i <= q;) { 63 | int now = x[i].value; 64 | 65 | while (pointer >= 1 and a[pointer].first > now) 66 | update(a[pointer].second, 1), --pointer; 67 | 68 | while (i <= q and x[i].value == now) 69 | res[x[i].id] = query(x[i].r) - query(x[i].l - 1), ++i; 70 | } 71 | 72 | for (int i = 1; i <= q; ++i) printf("%d\n", res[i]); 73 | return 0; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /SPOJ - Leaves.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Leaves (NKLEAVES) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Dynamic Programming, Convex Hull Trick 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int K = 14; 21 | const int N = 1e5 + 10; 22 | 23 | int n, k; 24 | long long w[N]; 25 | long long s[N]; 26 | long long dp[K][N]; 27 | vector m; 28 | vector c; 29 | int size, pointer; 30 | 31 | bool bad (int l1, int l2, int l3) { 32 | return (m[l1] - m[l2]) * (c[l3] - c[l1]) <= (c[l2] - c[l1]) * (m[l1] - m[l3]); 33 | } 34 | 35 | void add (long long m0, long long c0) { 36 | ++size; 37 | m.push_back(m0); 38 | c.push_back(c0); 39 | while (size >= 3 and bad(size - 3, size - 2, size - 1)) { 40 | --size; 41 | m.erase(m.end() - 2); 42 | c.erase(c.end() - 2); 43 | } 44 | } 45 | 46 | long long query (long long x) { 47 | if (pointer >= size) pointer = size - 1; 48 | while (pointer < size - 1 and m[pointer] * x + c[pointer] >= m[pointer + 1] * x + c[pointer + 1]) { 49 | ++pointer; 50 | } 51 | return m[pointer] * x + c[pointer]; 52 | } 53 | 54 | int main (int argc, char const *argv[]) { 55 | scanf("%d %d", &n, &k); 56 | for (int i = 1; i <= n; ++i) { 57 | scanf("%lld", s + i); 58 | w[i] = w[i - 1] + s[i] * i; 59 | s[i] += s[i - 1]; 60 | } 61 | for (int i = 1; i <= n; ++i) { 62 | dp[1][i] = w[i] - s[i]; 63 | } 64 | for (int i = 2; i <= k; ++i) { 65 | pointer = 0; 66 | for (int j = i; j <= n; ++j) { 67 | add(-j, dp[i - 1][j - 1] - w[j - 1] + j * s[j - 1]); 68 | dp[i][j] = w[j] + query(s[j]); 69 | } 70 | m.clear(), c.clear(), size = 0; 71 | } 72 | printf("%lld\n", dp[k][n]); 73 | return 0; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /SPOJ - Light Switching.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Light Switching (LITE) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree, Lazy Propagation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e5 + 10; 21 | 22 | struct node { 23 | int on, off, lazy; 24 | node () {} 25 | node (int a, int b, int c) : on(a), off(b), lazy(c) {} 26 | }; 27 | 28 | int n, m; 29 | node t[4 * N]; 30 | 31 | node merge (node a, node b) { 32 | return node(a.on + b.on, a.off + b.off, 0); 33 | } 34 | 35 | void propagate (int u, int b, int e) { 36 | swap(t[u].on, t[u].off); 37 | 38 | if (b != e) { 39 | ++t[u << 1].lazy, t[u << 1].lazy &= 1; 40 | ++t[u << 1 | 1].lazy, t[u << 1 | 1].lazy &= 1; 41 | } 42 | 43 | t[u].lazy = 0; 44 | } 45 | 46 | void build (int u, int b, int e) { 47 | if (b == e) { 48 | t[u] = node(0, 1, 0); 49 | return; 50 | } 51 | 52 | int l = u << 1, r = l | 1, m = b + e >> 1; 53 | build(l, b, m), build(r, m + 1, e); 54 | t[u] = merge(t[l], t[r]); 55 | } 56 | 57 | void update (int u, int b, int e, int p, int q) { 58 | if (t[u].lazy) propagate(u, b, e); 59 | if (b > q or e < p) return; 60 | if (b >= p and e <= q) { 61 | ++t[u].lazy; 62 | propagate(u, b, e); 63 | return; 64 | } 65 | 66 | int l = u << 1, r = l | 1, m = b + e >> 1; 67 | update(l, b, m, p, q), update(r, m + 1, e, p, q); 68 | t[u] = merge(t[l], t[r]); 69 | } 70 | 71 | int query (int u, int b, int e, int p, int q) { 72 | if (b > q or e < p) return 0; 73 | if (t[u].lazy) propagate(u, b, e); 74 | if (b >= p and e <= q) return t[u].on; 75 | 76 | int l = u << 1, r = l | 1, m = b + e >> 1; 77 | return query(l, b, m, p, q) + query(r, m + 1, e, p, q); 78 | } 79 | 80 | int main (int argc, char const *argv[]) { 81 | scanf("%d %d", &n, &m); 82 | build(1, 1, n); while (m--) { 83 | int cmd, l, r; 84 | scanf("%d %d %d", &cmd, &l, &r); 85 | 86 | if (cmd) printf("%d\n", query(1, 1, n, l, r)); 87 | else update(1, 1, n, l, r); 88 | } 89 | return 0; 90 | } 91 | 92 | -------------------------------------------------------------------------------- /SPOJ - Multiples of 3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Multiples of 3 (MULTQ3) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Segment Tree, Lazy Propagation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 1e5 + 10; 21 | 22 | struct node { 23 | int zero, one, two, lazy; 24 | node () {} 25 | node (int a, int b, int c, int d) : zero(a), one(b), two(c), lazy(d) {} 26 | }; 27 | 28 | int n, m; 29 | node t[4 * N]; 30 | 31 | node merge (node a, node b) { 32 | return node(a.zero + b.zero, a.one + b.one, a.two + b.two, 0); 33 | } 34 | 35 | void propagate (int u, int b, int e) { 36 | if (t[u].lazy == 1) { 37 | int tmp = t[u].two; 38 | t[u].two = t[u].one, t[u].one = t[u].zero, t[u].zero = tmp; 39 | } else { 40 | int tmp = t[u].zero; 41 | t[u].zero = t[u].one, t[u].one = t[u].two, t[u].two = tmp; 42 | } 43 | 44 | if (b != e) { 45 | t[u << 1].lazy += t[u].lazy, t[u << 1].lazy %= 3; 46 | t[u << 1 | 1].lazy += t[u].lazy, t[u << 1 | 1].lazy %= 3; 47 | } 48 | 49 | t[u].lazy = 0; 50 | } 51 | 52 | void build (int u, int b, int e) { 53 | if (b == e) { 54 | t[u] = node(1, 0, 0, 0); 55 | return; 56 | } 57 | 58 | int l = u << 1, r = l | 1, m = b + e >> 1; 59 | build(l, b, m), build(r, m + 1, e); 60 | t[u] = merge(t[l], t[r]); 61 | } 62 | 63 | void update (int u, int b, int e, int p, int q) { 64 | if (t[u].lazy) propagate(u, b, e); 65 | if (b > q or e < p) return; 66 | if (b >= p and e <= q) { 67 | ++t[u].lazy, t[u].lazy %= 3; 68 | propagate(u, b, e); 69 | return; 70 | } 71 | 72 | int l = u << 1, r = l | 1, m = b + e >> 1; 73 | update(l, b, m, p, q), update(r, m + 1, e, p, q); 74 | t[u] = merge(t[l], t[r]); 75 | } 76 | 77 | int query (int u, int b, int e, int p, int q) { 78 | if (b > q or e < p) return 0; 79 | if (t[u].lazy) propagate(u, b, e); 80 | if (b >= p and e <= q) return t[u].zero; 81 | 82 | int l = u << 1, r = l | 1, m = b + e >> 1; 83 | return query(l, b, m, p, q) + query(r, m + 1, e, p, q); 84 | } 85 | 86 | int main (int argc, char const *argv[]) { 87 | scanf("%d %d", &n, &m); 88 | build(1, 1, n); 89 | 90 | while (m--) { 91 | int cmd, l, r; 92 | scanf("%d %d %d", &cmd, &l, &r); 93 | ++l, ++r; 94 | 95 | if (cmd) printf("%d\n", query(1, 1, n, l, r)); 96 | else update(1, 1, n, l, r); 97 | } 98 | return 0; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /SPOJ - Query on a tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ - Query on a tree (QTREE) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Heavy-Light Decomposition, Segment Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int LG = 15; 21 | const int N = 1e4 + 10; 22 | 23 | char cmd[10]; 24 | int t, cs = 0, n; 25 | vector g[N], id[N], cost[N]; 26 | int tr[N + N], p[N][LG], depth[N]; 27 | int size[N], cur, pointer, pos[N]; 28 | int head[N], below[N], chain[N]; 29 | 30 | void dfs (int u, int par, int deep) { 31 | depth[u] = deep; 32 | p[u][0] = par; 33 | size[u] = 1; 34 | for (int i = 0; i < (int) g[u].size(); ++i) { 35 | int v = g[u][i], idx = id[u][i]; 36 | if (v == par) continue; 37 | below[idx] = v; 38 | dfs(v, u, deep + 1); 39 | size[u] += size[v]; 40 | } 41 | } 42 | 43 | void hld (int u, int curCost, int par) { 44 | if (head[cur] == -1) { 45 | head[cur] = u; 46 | } 47 | chain[u] = cur; 48 | pos[u] = pointer; 49 | tr[n + pointer] = curCost; 50 | ++pointer; 51 | int special = -1, nCost; 52 | for (int i = 0; i < (int) g[u].size(); ++i) { 53 | int v = g[u][i]; 54 | if (v == par) continue; 55 | if (special == -1 or size[special] < size[v]) { 56 | special = v; 57 | nCost = cost[u][i]; 58 | } 59 | } 60 | if (special != -1) { 61 | hld(special, nCost, u); 62 | } 63 | for (int i = 0; i < (int) g[u].size(); ++i) { 64 | int v = g[u][i]; 65 | if (v == par or v == special) continue; 66 | ++cur; 67 | hld(v, cost[u][i], u); 68 | } 69 | } 70 | 71 | void init (void) { 72 | for (int i = n - 1; i; --i) { 73 | tr[i] = max(tr[i << 1], tr[i << 1 | 1]); 74 | } 75 | } 76 | 77 | void tree_u (int p, int v) { 78 | for (tr[p += n] = v; p > 1; p >>= 1) { 79 | tr[p >> 1] = max(tr[p], tr[p ^ 1]); 80 | } 81 | } 82 | 83 | int tree_q (int l, int r) { 84 | int res = 0; 85 | for (l += n, r += n; l < r; l >>= 1, r >>= 1) { 86 | if (l & 1) res = max(res, tr[l++]); 87 | if (r & 1) res = max(res, tr[--r]); 88 | } 89 | return res; 90 | } 91 | 92 | int lca (int u, int v) { 93 | if (depth[u] < depth[v]) swap(u, v); 94 | for (int i = LG - 1; i >= 0; --i) { 95 | if (depth[u] - (1 << i) >= depth[v]) { 96 | u = p[u][i]; 97 | } 98 | } 99 | if (u == v) return u; 100 | for (int i = LG - 1; i >= 0; --i) { 101 | if (p[u][i] != -1 and p[u][i] != p[v][i]) { 102 | u = p[u][i], v = p[v][i]; 103 | } 104 | } 105 | return p[u][0]; 106 | } 107 | 108 | int subq (int u, int v) { 109 | if (u == v) return 0; 110 | int uchain, vchain = chain[v], res = -1; 111 | while (true) { 112 | uchain = chain[u]; 113 | if (uchain == vchain) { 114 | if (u == v) break; 115 | res = max(res, tree_q(1 + pos[v], 1 + pos[u])); 116 | break; 117 | } 118 | res = max(res, tree_q(pos[head[uchain]], 1 + pos[u])); 119 | u = p[head[uchain]][0]; 120 | } 121 | return res; 122 | } 123 | 124 | int query (int u, int v) { 125 | int w = lca(u, v); 126 | return max(subq(u, w), subq(v, w)); 127 | } 128 | 129 | void update (int p, int v) { 130 | int u = below[p]; 131 | tree_u(pos[u], v); 132 | } 133 | 134 | int main (int argc, char const *argv[]) { 135 | scanf("%d", &t); while (t--) { 136 | scanf("%d", &n); 137 | for (int i = 1; i < n; ++i) { 138 | int u, v, w; 139 | scanf("%d %d %d", &u, &v, &w); 140 | g[u].push_back(v); 141 | g[v].push_back(u); 142 | cost[u].push_back(w); 143 | cost[v].push_back(w); 144 | id[u].push_back(i); 145 | id[v].push_back(i); 146 | } 147 | memset(p, -1, sizeof p); 148 | memset(head, -1, sizeof head); 149 | dfs(1, 1, 0); 150 | pointer = cur = 0; 151 | hld(1, 0, 1); 152 | for (int i = 1; 1 << i <= n; ++i) { 153 | for (int j = 1; j <= n; ++j) { 154 | if (p[j][i - 1] != -1) { 155 | p[j][i] = p[p[j][i - 1]][i - 1]; 156 | } 157 | } 158 | } 159 | init(); 160 | while (scanf("%s", cmd) and cmd[0] != 'D') { 161 | int a, b; 162 | scanf("%d %d", &a, &b); 163 | if (cmd[0] == 'Q') { 164 | printf("%d\n", query(a, b)); 165 | } else { 166 | update(a, b); 167 | } 168 | } 169 | for (int i = 1; i <= n; ++i) { 170 | g[i].clear(); 171 | cost[i].clear(); 172 | id[i].clear(); 173 | } 174 | memset(tr, 0, sizeof tr); 175 | } 176 | return 0; 177 | } 178 | 179 | -------------------------------------------------------------------------------- /SPOJ - Seinfeld.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | SPOJ ANARC09A - Seinfeld 9 | 10 | Category: Ad hoc 11 | 12 | Keys: Compression, Simplification 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (i64) 1e14 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | string S; int L, i, Ret, Case = 1; 32 | 33 | int main() { 34 | cin.tie(nullptr); 35 | ios_base::sync_with_stdio(0); 36 | 37 | while (Case++) { 38 | cin >> S; if (S[0] == '-') break; 39 | 40 | stack Stack; L = S.length(); 41 | 42 | for (i = 0; i < L; i++) { 43 | if (Stack.empty()) Stack.push(S[i]); 44 | else if (S[i] == '}' && Stack.top() == '{') Stack.pop(); 45 | else Stack.push(S[i]); 46 | } 47 | 48 | S = ""; int open = 0, close = 0; 49 | 50 | while (!Stack.empty()) 51 | Stack.top() == '{' ? open++ : close++, Stack.pop(); 52 | 53 | Ret = open/2 + close/2 + 2 * (open % 2); 54 | cout << Case - 1 << ". " << Ret << endl; 55 | } 56 | 57 | cout.flush(); 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /TopCoder - BipartiteConstruction.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | TopCoder - BipartiteConstruction 9 | 10 | Category: Mathematics 11 | 12 | Keys: Constructive Algorithm, Combinatorics 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | class BipartiteConstruction {public: vector construct (int K);}; 21 | 22 | const int n = 20; 23 | 24 | vector BipartiteConstruction :: construct (int K) { 25 | vector edges; 26 | edges.push_back(n); 27 | 28 | for (int i = n - 1; i; --i) { 29 | edges.push_back(i * n + i); 30 | for (int j = 0; j < 3; ++j) edges.push_back(i * n + i - 1); 31 | } 32 | 33 | int node = 0; while (K) { 34 | int r = K % 3; 35 | K /= 3; 36 | for (int i = 0; i < r; ++i) edges.push_back(node); 37 | ++node; 38 | } 39 | 40 | return edges; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /TopCoder - DarkMatterParticles.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | TopCoder - DarkMatterParticles 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Coin Change 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | class DarkMatterParticles {public: string SplitParticles (int n, int k, vector x, vector y);}; 21 | 22 | const int N = 1010; 23 | 24 | int currSize; 25 | bool vis[N], dp[N][N]; 26 | vector g[N], comp; 27 | 28 | void dfs (int u) { 29 | if (vis[u]) return; 30 | ++currSize, vis[u] = 1; 31 | for (int j = 0; j < g[u].size(); ++j) { 32 | int v = g[u][j]; 33 | dfs(v); 34 | } 35 | } 36 | 37 | string DarkMatterParticles :: SplitParticles (int n, int k, vector x, vector y) { 38 | for (int i = 0; i < x.size(); ++i) { 39 | g[x[i]].push_back(y[i]); 40 | g[y[i]].push_back(x[i]); 41 | } 42 | 43 | comp.push_back(-1); 44 | for (int i = 0; i < n; ++i) if (not vis[i]) { 45 | currSize = 0, dfs(i); 46 | comp.push_back(currSize); 47 | } 48 | 49 | dp[0][0] = 1; 50 | int m = comp.size() - 1; 51 | for (int i = 1; i <= m; ++i) 52 | for (int j = 0; j < N; ++j) 53 | if (j - comp[i] >= 0 and dp[i - 1][j - comp[i]]) 54 | dp[i][j - comp[i]] = dp[i][j] = 1; 55 | 56 | if (dp[m][k]) return "Possible"; 57 | return "Impossible"; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Toph - Act of Random Kindness.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | Toph - Act of Random Kindness 9 | 10 | Category: Data Structure, Mathematics 11 | 12 | Keys: Union Find, Counting 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (i64) 1e14 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX 1000005 31 | 32 | i64 N, u, v, Ret = 0, R[MAX], P[MAX], F[MAX]; 33 | 34 | void MakeSet (void) { 35 | for (int i = 0; i < MAX; i++) P[i] = i, R[i] = 0, F[i] = 1; 36 | } 37 | 38 | i64 Find (i64 x) { 39 | return P[x] == x ? x : P[x] = Find(P[x]); 40 | } 41 | 42 | void Union (i64 x, i64 y) { 43 | i64 x_root = Find(x), y_root = Find(y); 44 | if (x_root == y_root) return; 45 | 46 | if (R[x_root] < R[y_root]) 47 | P[x_root] = y_root, F[y_root] += F[x_root]; 48 | 49 | else if (R[x_root] > R[y_root]) 50 | P[y_root] = x_root, F[x_root] += F[y_root]; 51 | 52 | else 53 | P[y_root] = x_root, ++R[x_root], F[x_root] += F[y_root]; 54 | } 55 | 56 | int main () { 57 | MakeSet(); scanf ("%lld", &N); 58 | while (N--) { 59 | scanf ("%lld %lld", &u, &v); 60 | if (Find(u) != Find(v)) Ret += F[Find(u)] * F[Find(v)]; 61 | Union(u, v); printf ("%lld\n", Ret); 62 | } 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /USACO - Agri-Net.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Agri-Net 9 | 10 | Category: Graph Theory 11 | 12 | Keys: Minimal Spanning Tree, Prim's Algorithm 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX 105 31 | 32 | bool Mark[MAX]; 33 | int Adj[MAX][MAX], N, i, j, Dist[MAX], Mate[MAX]; 34 | 35 | void Read (void) { 36 | scanf("%d", &N); 37 | for (i = 1; i <= N; i++) 38 | for (j = 1; j <= N; j++) 39 | scanf("%d", *(Adj + i) + j); 40 | } 41 | 42 | int Find_Node (void) { 43 | int MinDist = inf, ID; 44 | for (j = 1; j <= N; j++) 45 | if (!Mark[j] && Dist[j] < MinDist) 46 | MinDist = Dist[j], ID = j; 47 | return ID; 48 | } 49 | 50 | int Prim (void) { 51 | memset(Mark, 0, sizeof Mark); 52 | memset(Mate, -1, sizeof Mate); 53 | for (i = 1; i <= N; i++) Dist[i] = inf; 54 | 55 | int Cost = 0, Size = 1; Mark[1] = true; 56 | for (j = 2; j <= N; j++) if (Adj[1][j]) 57 | Dist[j] = Adj[1][j], Mate[j] = 1; 58 | 59 | while (Size < N) { 60 | i = Find_Node(); 61 | Size++, Cost += Dist[i], Mark[i] = true; 62 | for (j = 1; j <= N; j++) 63 | if (Adj[i][j] && Dist[j] > Adj[i][j]) 64 | Dist[j] = Adj[i][j], Mate[j] = i; 65 | } 66 | return Cost; 67 | } 68 | 69 | int main () { 70 | freopen("agrinet.in", "r", stdin); 71 | freopen("agrinet.out", "w", stdout); 72 | 73 | Read(); 74 | printf("%d\n", Prim()); 75 | 76 | return 0; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /USACO - Contact.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Contact 9 | 10 | Category: Implementation, String 11 | 12 | Keys: C++ STL, Brute Force 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)2e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX 200005 31 | 32 | string S, in; 33 | map M; 34 | int A, B, N, i, j, L, cnt, k; 35 | vector< pair > V; 36 | map::iterator it; 37 | vector< pair< int, vector > > R; 38 | 39 | bool cmp (pair A, pair B) { 40 | if (A.first == B.first) { 41 | if (A.second.length() == B.second.length()) 42 | return (A.second < B.second); 43 | return A.second.length() < B.second.length(); 44 | } 45 | return A.first > B.first; 46 | } 47 | 48 | int main () { 49 | freopen("contact.in", "r", stdin); 50 | freopen("contact.out", "w", stdout); 51 | 52 | cin >> A >> B >> N; S = ""; 53 | while (cin >> in) S += in; 54 | L = S.length(); 55 | 56 | for (i = A; i <= B; i++) 57 | for (j = 0; j <= L - i; j++) 58 | ++M[S.substr(j, i)]; 59 | 60 | for (it = M.begin(); it != M.end(); ++it) 61 | V.push_back(make_pair(it -> second, it -> first)); 62 | sort(V.begin(), V.end(), cmp); 63 | 64 | i = 1, j = 0; R.resize(MAX); 65 | R[0].first = V[0].first, R[0].second.push_back(V[0].second); 66 | while (i < V.size()) { 67 | if (V[i].first != V[i - 1].first) R[++j].first = V[i].first; 68 | R[j].second.push_back(V[i++].second); 69 | } 70 | 71 | for (i = 0; i < N && i <= j; i++) { 72 | cnt = 0; cout << R[i].first << endl; 73 | for (k = 0; k < R[i].second.size(); k++) { 74 | if (cnt == 6) { 75 | cout << endl; 76 | cnt = 0; 77 | } 78 | if (cnt != 0) cout << " "; 79 | cout << R[i].second[k]; ++cnt; 80 | } cout << endl; 81 | } 82 | return 0; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /USACO - Cow Pedigrees.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Cow Pedigrees 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Bottom Up (Iterative DP) 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | 30 | #define mod 9901 31 | #define MAX 205 32 | 33 | int DP[MAX][MAX], N, K, i, j, k; 34 | 35 | ifstream fin ("nocows.in"); 36 | ofstream fout ("nocows.out"); 37 | 38 | void Kill (void) { 39 | fin >> N >> K; 40 | memset(DP, 0, sizeof DP); 41 | for (i = 1; i <= K; i++) DP[1][i] = 1; 42 | for (i = 2; i <= N; i++) 43 | for (j = 2; j <= K; j++) 44 | for (k = 1; k + 2 <= i; k++) 45 | DP[i][j] = (DP[i][j] + DP[k][j - 1] * DP[i - k - 1][j - 1]) % mod; 46 | fout << (DP[N][K] - DP[N][K - 1] + mod) % mod << endl; 47 | } 48 | 49 | int main() { 50 | Kill(); 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /USACO - Cow Tours.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Cow Tours 9 | 10 | Category: Graph Theory, All Pairs Shortest Path 11 | 12 | Keys: Floyd Warshall, Flood Fill 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (double)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX 154 31 | 32 | struct node {int x, y;}; 33 | 34 | int N, i, j, k; 35 | node A[MAX]; string row; 36 | double Dist[MAX][MAX], Far[MAX], Ret; 37 | 38 | double Length (node A, node B) { 39 | return hypot(A.x - B.x, A.y - B.y); 40 | } 41 | 42 | void Fill (void) { 43 | for (i = 0; i < MAX; i++) 44 | for (j = 0; j < MAX; j++) 45 | Dist[i][j] = inf; 46 | } 47 | 48 | void Read (void) { 49 | cin >> N; 50 | for (i = 1; i <= N; i++) cin >> A[i].x >> A[i].y; 51 | for (i = 1; i <= N; i++) { 52 | cin >> row; 53 | for (j = 1; j <= N; j++) if (row[j - 1] - '0') 54 | Dist[i][j] = Length(A[i], A[j]); 55 | } 56 | } 57 | 58 | void Floyd_Warshall (void) { 59 | for (k = 1; k <= N; k++) 60 | for (i = 1; i <= N; i++) 61 | for (j = 1; j <= N; j++) 62 | Dist[i][j] = min(Dist[i][j], Dist[i][k] + Dist[k][j]); 63 | 64 | for (i = 1; i <= N; i++) Dist[i][i] = 0; 65 | } 66 | 67 | void Farthest (void) { 68 | memset(Far, 0, sizeof Far); 69 | for (i = 1; i <= N; i++) 70 | for (j = 1; j <= N; j++) 71 | if (Dist[i][j] != inf) 72 | Far[i] = max(Far[i], Dist[i][j]); 73 | } 74 | 75 | void Connect_And_Check (void) { 76 | Ret = inf; 77 | for (i = 1; i <= N; i++) 78 | for (j = 1; j <= N; j++) 79 | if (Dist[i][j] == inf) 80 | Ret = min(Ret, Far[i] + Length(A[i], A[j]) + Far[j]); 81 | } 82 | 83 | void Print (void) { 84 | for (i = 1; i <= N; i++) Ret = max(Ret, Far[i]); 85 | printf("%0.6lf\n", Ret); 86 | } 87 | 88 | int main() { 89 | freopen("cowtour.in", "r", stdin); 90 | freopen("cowtour.out", "w", stdout); 91 | 92 | Fill(); 93 | Read(); 94 | Floyd_Warshall(); 95 | Farthest(); 96 | Connect_And_Check(); 97 | Print(); 98 | 99 | return 0; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /USACO - Factorials.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Factorials 9 | 10 | Category: Mathematics 11 | 12 | Keys: Recursive Descent, Observation 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | typedef pair pii; 23 | 24 | #define checkbit(n, b) ((n >> b) & 1) 25 | #define gcd __gcd 26 | #define bitcount __bultin_popcount 27 | #define inf (int)2e9 28 | #define eps 1e-9 29 | #define pi acos(-1) 30 | #define mod 1000000007 31 | #define MAX 4225 32 | 33 | int N, F[] = {1, 1, 2, 6, 4}, Two[] = {6, 2, 4, 8}; 34 | 35 | int Ans (int n) { 36 | if (n < 5) return F[n]; 37 | int q = n / 5, r = n % 5; 38 | return (Ans(q) * Two[q % 4] * F[r]) % 10; 39 | } 40 | 41 | int main () { 42 | freopen("fact4.in", "r", stdin); 43 | freopen("fact4.out", "w", stdout); 44 | cin >> N; cout << Ans(N) << endl; 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /USACO - Home on the Range.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Home on the Range 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Bottom Up 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 255; 21 | 22 | char g[N][N]; 23 | int n, dp[N][N], res[N]; 24 | 25 | int main (int argc, char const *argv[]) { 26 | freopen("range.in", "r", stdin); 27 | freopen("range.out", "w", stdout); 28 | 29 | scanf("%d", &n); 30 | for (int i = 1; i <= n; ++i) scanf("%s", g[i] + 1); 31 | 32 | for (int i = 1; i <= n; ++i) 33 | dp[1][i] = (g[1][i] - '0'), dp[i][1] = (g[i][1] - '0'); 34 | 35 | for (int i = 2; i <= n; ++i) 36 | for (int j = 2; j <= n; ++j) 37 | dp[i][j] = g[i][j] == '0' ? 0 : 1 + min(dp[i - 1][j - 1], min(dp[i][j - 1], dp[i - 1][j])); 38 | 39 | for (int i = 1; i <= n; ++i) 40 | for (int j = 1; j <= n; ++j) 41 | ++res[1], --res[dp[i][j] + 1]; 42 | 43 | for (int i = 1; i <= n; ++i) { 44 | res[i] += res[i - 1]; 45 | if (i > 1 and res[i]) printf("%d %d\n", i, res[i]); 46 | } 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /USACO - Humble Numbers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Humble Numbers 9 | 10 | Category: Ad hoc, Implementation 11 | 12 | Keys: Brute Force, Greedy 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)2e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX_K 105 31 | #define MAX_N 100005 32 | 33 | vector V; 34 | int K, N, i, j, ID[MAX_K], P[MAX_K], H[MAX_N]; 35 | 36 | void Read (void) { 37 | cin >> K >> N; 38 | for (i = 1; i <= K; i++) cin >> P[i]; 39 | memset(ID, 0, sizeof ID); H[0] = 1; 40 | } 41 | 42 | int Next_Humble_Number (void) { 43 | int Ret = inf; V.clear(); 44 | for (i = 1; i <= K; i++) { 45 | if (P[i] * H[ID[i]] <= Ret) { 46 | if (P[i] * H[ID[i]] < Ret) V.clear(); 47 | V.push_back(i); Ret = P[i] * H[ID[i]]; 48 | } 49 | } 50 | for (i = 0; i < V.size(); i++) ++ID[V[i]]; 51 | return Ret; 52 | } 53 | 54 | int main () { 55 | freopen("humble.in", "r", stdin); 56 | freopen("humble.out", "w", stdout); 57 | 58 | Read(); 59 | for (j = 1; j <= N; j++) H[j] = Next_Humble_Number(); 60 | cout << H[N] << endl; 61 | 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /USACO - Longest Prefix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Longest Prefix (IOI 1996) 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Bottom Up (Iterative DP) 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | #define MAX 200005 32 | #define max(a, b) (a > b ? a : b) 33 | 34 | bool DP[MAX]; 35 | string S, inp; 36 | vector Prims; 37 | int i, j, len, cnt, Res; 38 | 39 | ifstream fin ("prefix.in"); 40 | ofstream fout ("prefix.out"); 41 | 42 | void Read (void) { 43 | cnt = 0, S = ""; 44 | while (fin >> inp && inp != ".") 45 | Prims.push_back(inp), ++cnt; 46 | while (fin >> inp) S += inp; 47 | } 48 | 49 | void Kill (void) { 50 | memset(DP, false, sizeof DP); 51 | DP[0] = true, Res = 0, len = S.length(); 52 | for (i = 0; i < len; i++) 53 | if (DP[i]) 54 | for (j = 0; j < cnt; j++) 55 | if (S.substr(i, Prims[j].length()) == Prims[j]) 56 | DP[i + Prims[j].length()] = true, 57 | Res = max(Res, i + Prims[j].length()); 58 | fout << Res << endl; 59 | } 60 | 61 | int main() { 62 | Read(); 63 | Kill(); 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /USACO - Money Systems.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Money Systems 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Coin Change, Top Down (Recursive DP) 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX 10002 31 | 32 | ifstream fin ("money.in"); 33 | ofstream fout ("money.out"); 34 | 35 | i64 DP[MAX][30], V, N, i, Coin[30]; 36 | 37 | i64 Call (i64 n, i64 k) { 38 | if (n == 0) return 1; 39 | if (n < 0) return 0; 40 | if (k <= 0) return 0; 41 | if (DP[n][k] != -1) return DP[n][k]; 42 | return DP[n][k] = Call(n, k - 1) + Call(n - Coin[k], k); 43 | } 44 | 45 | void Kill (void) { 46 | fin >> V >> N; 47 | for (i = 1; i <= V; i++) fin >> Coin[i]; 48 | memset(DP, -1, sizeof DP); 49 | fout << Call(N, V) << endl; 50 | } 51 | 52 | int main() { 53 | Kill(); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /USACO - Overfencing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Overfencing 9 | 10 | Category: Graph Theory, Shortest Path 11 | 12 | Keys: Breadth First Search 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | typedef pair pii; 23 | 24 | #define checkbit(n, b) ((n >> b) & 1) 25 | #define gcd __gcd 26 | #define bitcount __bultin_popcount 27 | #define inf (int)1e9 28 | #define eps 1e-9 29 | #define pi acos(-1) 30 | #define mod 1000000007 31 | 32 | #define f first 33 | #define s second 34 | 35 | char G[205][80]; string row; 36 | int a, b, c, d, i, j, k, H, W, ret; 37 | int Dist1[205][80], Dist2[205][80]; 38 | 39 | int dx[] = {-1, 0, 1, 0}; 40 | int dy[] = {0, 1, 0, -1}; 41 | 42 | bool Valid (int x, int y) { 43 | return x >= 1 && x <= 2 * H + 1 && y >= 1 && y <= 2 * W + 1 && G[x][y] != '*'; 44 | } 45 | 46 | void Read (void) { 47 | cin >> W >> H; bool flag = 0; 48 | getline(cin, row); 49 | 50 | for (i = 1; i <= 2 * H + 1; i++) { 51 | getline(cin, row); 52 | for (j = 1; j <= 2 * W + 1; j++) { 53 | if (row[j - 1] == ' ') G[i][j] = '.'; 54 | else G[i][j] = '*'; 55 | 56 | if (i == 1 or i == 2 * H + 1 or j == 1 or j == 2 * W + 1) { 57 | if (G[i][j] == '.') { 58 | if (flag) c = i, d = j; 59 | else a = i, b = j, flag = 1; 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | void BFS (int a, int b, int (&Dist)[205][80]) { 67 | int now_x, now_y; 68 | queue< pii > Q; pii P, C; 69 | Dist[a][b] = 0, Q.push(make_pair(a,b)); 70 | 71 | while (!Q.empty()) { 72 | C = Q.front(); Q.pop(); 73 | for (k = 0; k < 4; k++) { 74 | now_x = C.f + dx[k], now_y = C.s + dy[k]; 75 | if (Valid(now_x, now_y)) 76 | if (Dist[now_x][now_y] == -1) 77 | Dist[now_x][now_y] = Dist[C.f][C.s] + 1, 78 | Q.push(make_pair(now_x, now_y)); 79 | } 80 | } 81 | } 82 | 83 | void Kill (void) { 84 | ret = 0; 85 | memset(Dist1, -1, sizeof Dist1); 86 | memset(Dist2, -1, sizeof Dist2); 87 | 88 | BFS(a, b, Dist1); BFS(c, d, Dist2); 89 | 90 | for (i = 1; i <= 2 * H + 1; i++) 91 | for (j = 1; j <= 2 * W + 1; j++) 92 | if (G[i][j] != '*') 93 | ret = max(ret, min(Dist1[i][j], Dist2[i][j])); 94 | 95 | cout << ceil(ret / 2.0) << endl; 96 | } 97 | 98 | int main() { 99 | freopen("maze1.in", "r", stdin); 100 | freopen("maze1.out", "w", stdout); 101 | 102 | Read(), Kill(); 103 | return 0; 104 | } 105 | 106 | -------------------------------------------------------------------------------- /USACO - Riding The Fences.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Riding The Fences 9 | 10 | Category: Graph Theory 11 | 12 | Keys: Euler Circuit/Path 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 505; 21 | 22 | stack tour; 23 | int f, g[N][N], deg[N]; 24 | 25 | void eulerTour (int u) { 26 | if (deg[u] == 0) { 27 | tour.push(u); 28 | return; 29 | } 30 | 31 | while (deg[u]) { 32 | int v = 1; 33 | while (!g[u][v]) ++v; 34 | --g[u][v], --g[v][u], --deg[u], --deg[v]; 35 | eulerTour(v); 36 | } 37 | 38 | tour.push(u); 39 | } 40 | 41 | int main (int argc, char const *argv[]) { 42 | freopen("fence.in", "r", stdin); 43 | freopen("fence.out", "w", stdout); 44 | 45 | scanf("%d", &f); while (f--) { 46 | int u, v; 47 | scanf("%d %d", &u, &v); 48 | ++g[u][v], ++g[v][u], ++deg[u], ++deg[v]; 49 | } 50 | 51 | int start; 52 | for (int i = 1; i < N; ++i) if (deg[i]) {start = i; break;} 53 | for (int i = 1; i < N; ++i) if (deg[i] & 1) {start = i; break;} 54 | 55 | eulerTour(start); 56 | while (not tour.empty()) printf("%d\n", tour.top()), tour.pop(); 57 | return 0; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /USACO - Score Inflation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Score Inflation 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Bottom Up (Iterative DP) 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | #define MAX 10005 31 | 32 | int DP[MAX], M, N, a, b, i; 33 | 34 | int main () { 35 | freopen("inflate.in", "r", stdin); 36 | freopen("inflate.out", "w", stdout); 37 | 38 | memset(DP, 0, sizeof DP); 39 | cin >> M >> N; while (N--) { 40 | cin >> a >> b; 41 | for (i = 0; i + b <= MAX; i++) 42 | DP[i + b] = max(DP[i + b], DP[i] + a); 43 | } 44 | cout << DP[M] << endl; 45 | 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /USACO - Shopping Offers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - Shopping Offers (IOI '95) 9 | 10 | Category: Dynamic Programming 11 | 12 | Keys: Generalizing States 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 6; 21 | const int S = 110; 22 | const int C = 1010; 23 | const int INF = 1e9 + 10; 24 | 25 | int s, b, size[S], cost[C], take[N], init[N]; 26 | int package[S][C], offerPrice[S], dp[N][N][N][N][N]; 27 | 28 | int call (int a, int b, int c, int d, int e) { 29 | if (a < 0 or b < 0 or c < 0 or d < 0 or e < 0) return INF; 30 | if (a == 0 and b == 0 and c == 0 and d == 0 and e == 0) return 0; 31 | if (dp[a][b][c][d][e] != -1) return dp[a][b][c][d][e]; 32 | 33 | int ret = INF; 34 | 35 | for (int i = 1; i <= s; ++i) { 36 | int na, nb, nc, nd, ne; 37 | na = a - package[i][take[1]]; 38 | nb = b - package[i][take[2]]; 39 | nc = c - package[i][take[3]]; 40 | nd = d - package[i][take[4]]; 41 | ne = e - package[i][take[5]]; 42 | ret = min(ret, offerPrice[i] + call(na, nb, nc, nd, ne)); 43 | } 44 | 45 | for (int i = 1; i <= a; ++i) ret = min(ret, i * cost[1] + call(a - i, b, c, d, e)); 46 | for (int i = 1; i <= b; ++i) ret = min(ret, i * cost[2] + call(a, b - i, c, d, e)); 47 | for (int i = 1; i <= c; ++i) ret = min(ret, i * cost[3] + call(a, b, c - i, d, e)); 48 | for (int i = 1; i <= d; ++i) ret = min(ret, i * cost[4] + call(a, b, c, d - i, e)); 49 | for (int i = 1; i <= e; ++i) ret = min(ret, i * cost[5] + call(a, b, c, d, e - i)); 50 | 51 | return dp[a][b][c][d][e] = ret; 52 | } 53 | 54 | int main (int argc, char const *argv[]) { 55 | freopen("shopping.in", "r", stdin); 56 | freopen("shopping.out", "w", stdout); 57 | 58 | scanf("%d", &s); 59 | for (int i = 1; i <= s; ++i) { 60 | scanf("%d", size + i); 61 | for (int j = 1; j <= size[i]; ++j) { 62 | int x, y; 63 | scanf("%d %d", &x, &y); 64 | package[i][x] = y; 65 | } 66 | scanf("%d", offerPrice + i); 67 | } 68 | scanf("%d", &b); 69 | for (int i = 1; i <= b; ++i) scanf("%d %d %d", take + i, init + i, cost + i); 70 | 71 | memset(dp, -1, sizeof dp); 72 | printf("%d\n", call(init[1], init[2], init[3], init[4], init[5])); 73 | return 0; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /USACO - The Tamworth Two.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | USACO - The Tamworth Two 9 | 10 | Category: Ad hoc 11 | 12 | Keys: Simulation, Brute Force 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | typedef long long i64; 21 | typedef unsigned long long ui64; 22 | 23 | #define checkbit(n, b) ((n >> b) & 1) 24 | #define gcd __gcd 25 | #define bitcount __bultin_popcount 26 | #define inf (int)1e9 27 | #define eps 1e-9 28 | #define pi acos(-1) 29 | #define mod 1000000007 30 | 31 | #define lim 100000 32 | 33 | char Grid[11][11]; 34 | int i, j, a, b, c, d, F, C, t; 35 | 36 | int dx[] = {-1, 0, 1, 0}; 37 | int dy[] = {0, 1, 0, -1}; 38 | 39 | bool Valid (int x, int y) { 40 | return x >= 1 && x <= 10 && y >= 1 && y <= 10 && Grid[x][y] != '*'; 41 | } 42 | 43 | void Move (void) { 44 | if (Valid(a + dx[F], b + dy[F])) a += dx[F], b += dy[F]; 45 | else F = (F + 1) % 4; 46 | 47 | if (Valid(c + dx[C], d + dy[C])) c += dx[C], d += dy[C]; 48 | else C = (C + 1) % 4; 49 | } 50 | 51 | int main() { 52 | freopen("ttwo.in", "r", stdin); 53 | freopen("ttwo.out", "w", stdout); 54 | 55 | for (i = 1; i <= 10; i++) { 56 | for (j = 1; j <= 10; j++) { 57 | cin >> Grid[i][j]; 58 | if (Grid[i][j] == 'F') a = i, b = j; 59 | else if (Grid[i][j] == 'C') c = i, d = j; 60 | } 61 | } 62 | 63 | F = 0, C = 0, t = 0; 64 | for (i = 0; i < lim; i++) { 65 | Move(), t++; 66 | if (a == c && b == d) { 67 | cout << t << endl; 68 | return 0; 69 | } 70 | } 71 | 72 | cout << 0 << endl; 73 | return 0; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /UVa 11492.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | UVa 11492 - Babel 9 | 10 | Category: Graph Theory, Shortest Path 11 | 12 | Keys: Graph Modeling 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int N = 4010; 21 | const int INF = 2e9 + 100; 22 | 23 | struct data { 24 | int to, weight, start; 25 | data () {} 26 | data (int _t, int _w, int _s) : to(_t), weight(_w), start(_s) {} 27 | }; 28 | 29 | struct state { 30 | int label, cost, letter; 31 | state () {} 32 | state (int _l, int _c, int _f) : label(_l), cost(_c), letter(_f) {} 33 | bool operator < (const state &s) const { 34 | return cost > s.cost; 35 | } 36 | }; 37 | 38 | vector g[N]; 39 | map Map; 40 | int m, n, s, d, dist[N][30]; 41 | string O, D; 42 | 43 | int Dijkstra (void) { 44 | for (int i = 1; i <= n; ++i) 45 | for (int j = 0; j < 26; ++j) dist[i][j] = INF; 46 | priority_queue PQ; 47 | PQ.push(state(Map[O], 0, 26)); 48 | for (int i = 0; i < 26; ++i) dist[0][i] = 0; 49 | 50 | while (not PQ.empty()) { 51 | state S = PQ.top(); PQ.pop(); 52 | for (data d : g[S.label]) { 53 | if (d.start == S.letter) continue; 54 | if (S.cost + d.weight < dist[d.to][d.start]) { 55 | dist[d.to][d.start] = S.cost + d.weight; 56 | PQ.push(state(d.to, dist[d.to][d.start], d.start)); 57 | } 58 | } 59 | } 60 | 61 | int result = INF; 62 | for (int i = 0; i < 26; ++i) result = min(result, dist[Map[D]][i]); 63 | if (result == INF) result = -1; 64 | return result; 65 | } 66 | 67 | int main (int argc, char const *argv[]) { 68 | while (scanf("%d", &m) and m) { 69 | Map.clear(); 70 | for (int i = 0; i < N; ++i) g[i].clear(); 71 | n = 0; 72 | 73 | cin >> O >> D; 74 | Map[O] = ++n; 75 | if (O == D) Map[D] = Map[O]; 76 | else Map[D] = ++n; 77 | 78 | for (int i = 0; i < m; ++i) { 79 | string u, v, w; 80 | cin >> u >> v >> w; 81 | 82 | if (not Map.count(u)) Map[u] = ++n; 83 | if (not Map.count(v)) Map[v] = ++n; 84 | 85 | g[Map[u]].push_back(data(Map[v], w.size(), w[0] - 'a')); 86 | g[Map[v]].push_back(data(Map[u], w.size(), w[0] - 'a')); 87 | } 88 | 89 | int cost = Dijkstra(); 90 | 91 | if (cost == -1) printf("impossivel\n"); 92 | else printf("%d\n", cost); 93 | } 94 | return 0; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /UVa 11990.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | |\ | `|` |``\ ```|` | | /```\ |``\ 4 | | \ | | |__/ | |___| | | |__/ 5 | | \ | | | \ | | | | | | \ 6 | _| \| _|_ | \ \__) | | \___/ | \ 7 | 8 | UVa 11990 - Dynamic Inversion - O(n lg(n) lg(n)) 9 | 10 | Category: Data Structures 11 | 12 | Keys: Merge Sort Tree, Fenwick Tree 13 | 14 | */ 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int H = 20; 21 | const int N = 200010; 22 | const int INF = 1e9 + 10; 23 | 24 | int n, m, a[N], pos[N], size[3 * N]; 25 | vector t[3 * N], bit[3 * N], inv_bit(N); 26 | 27 | void updateBIT (vector &bit, int p, int v, int MAX) { 28 | while (p <= MAX) bit[p - 1] += v, p += (p & -p); 29 | } 30 | 31 | int queryBIT (vector &bit, int p) { 32 | int sum = 0; 33 | while (p > 0) sum += bit[p - 1], p -= (p & -p); 34 | return sum; 35 | } 36 | 37 | void merge (int u, int b, int e) { 38 | int l = u << 1, r = l | 1; 39 | int L = size[l], R = size[r]; 40 | t[l].push_back(INF), t[r].push_back(INF); 41 | 42 | size[u] = L + R, bit[u].clear(), bit[u].resize(size[u], 0); 43 | for (int i = 1; i <= size[u]; ++i) updateBIT(bit[u], i, 1, size[u]); 44 | 45 | t[u].clear(); 46 | for (int i = 0, j = 0; i < L or j < R;) { 47 | if (t[l][i] < t[r][j]) t[u].push_back(t[l][i++]); 48 | else t[u].push_back(t[r][j++]); 49 | } 50 | 51 | t[l].pop_back(), t[r].pop_back(); 52 | } 53 | 54 | void init (int u, int b, int e) { 55 | if (b == e) { 56 | t[u].clear(), bit[u].clear(); 57 | size[u] = 1, bit[u].resize(size[u], 0); 58 | updateBIT(bit[u], 1, 1, size[u]); 59 | t[u].push_back(a[b]); 60 | return; 61 | } 62 | 63 | int l = u << 1, r = l | 1, m = b + e >> 1; 64 | init(l, b, m), init(r, m + 1, e); 65 | merge(u, b, e); 66 | } 67 | 68 | void updateSegTree (int u, int b, int e, int p, int x) { 69 | if (p > e or p < b) return; 70 | if (p >= b and p <= e) { 71 | int pos = lower_bound(t[u].begin(), t[u].end(), x) - t[u].begin(); 72 | updateBIT(bit[u], pos + 1, -1, size[u]); 73 | if (b == e) return; 74 | } 75 | 76 | int l = u << 1, r = l | 1, m = b + e >> 1; 77 | updateSegTree(l, b, m, p, x), updateSegTree(r, m + 1, e, p, x); 78 | } 79 | 80 | int querySegTree (int u, int b, int e, int p, int q, int x, int side) { 81 | if (p > q or b > q or e < p) return 0; 82 | if (b >= p and e <= q) { 83 | int tot = upper_bound(t[u].begin(), t[u].end(), x) - t[u].begin(); 84 | if (side) return queryBIT(bit[u], tot); 85 | return queryBIT(bit[u], size[u]) - queryBIT(bit[u], tot); 86 | } 87 | 88 | int l = u << 1, r = l | 1, m = b + e >> 1; 89 | return querySegTree(l, b, m, p, q, x, side) + querySegTree(r, m + 1, e, p, q, x, side); 90 | } 91 | 92 | int main (int argc, char const *argv[]) { 93 | while (scanf("%d %d", &n, &m) == 2) { 94 | for (int i = 1; i <= n; ++i) { 95 | scanf("%d", a + i); 96 | pos[a[i]] = i; 97 | } 98 | 99 | init(1, 1, n); 100 | fill(inv_bit.begin(), inv_bit.end(), 0); 101 | 102 | long long inversions = 0; 103 | for (int i = n; i; --i) { 104 | inversions += (long long) queryBIT(inv_bit, pos[i]); 105 | updateBIT(inv_bit, pos[i], 1, N - 1); 106 | } 107 | 108 | while (m--) { 109 | printf("%lld\n", inversions); 110 | int x; scanf("%d", &x); 111 | inversions -= querySegTree(1, 1, n, 1, pos[x] - 1, x, 0); 112 | inversions -= querySegTree(1, 1, n, pos[x] + 1, n, x, 1); 113 | updateSegTree(1, 1, n, pos[x], x); 114 | } 115 | } 116 | return 0; 117 | } 118 | 119 | 120 | --------------------------------------------------------------------------------