题目
1. 栈
#A 表达式的转换 (Unaccepted)
2. STL 模板库
#B 双栈排序(Unaccepted)
#C 垃圾陷阱(Accepted)
#D 合并果子(Accepted)
#E 统计数字(Unaccepted)
#F 小木棍 [数据加强版](Unaccepted)
3. 树状数组
4. 归并排序
#H 逆序对(Unaccepted)
5. 最大子矩形
#A 最大正方形(Unaccepted)
#B 奶牛浴场(Accepted)
#C 最大加权矩形(Unaccepted)
#D [ZJOI2007]棋盘制作 (Unaccepted)
1. 棋盘问题
/* Luogu P1549 棋盘问题(2) * Au: GG */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> const int N = 12; int n, m, d[N][N]; bool numlist[N * N]; bool isprime(int x) { int sq = sqrt(x); for (int i = 2; i <= sq; i++) if (x % i == 0) return false; return true; } bool dfs(int x, int y, int num) { if (x > 1) if (!isprime(num + d[x - 1][y])) return false; if (y > 1) if (!isprime(num + d[x][y - 1])) return false; d[x][y] = num; numlist[num] = true; if (x == n && y == n) return true; int ax = x, ay = y; if (ay == n) ay = 1, ax++; else ay++; for (int i = 1; i <= n * n; i++) if (!numlist[i]) if (dfs(ax, ay, i)) return true; numlist[num] = false; return false; } int main() { scanf("%d", &n); if (n == 1) { printf("NO "); return 0; } if (dfs(1, 1, 1)) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { printf("%d", d[i][j]); if (j < n) printf(" "); } printf(" "); } } else printf("NO "); return 0; }
2. 斐波那契数列
/* Luogu P2626 斐波那契数列(升级版) * Au: GG */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> using namespace std; const int N = 50; const long long mod = 2147483648ll; int n, fd[N], pd[N], ptop = 1; int Fibonacci(int x) { if (x == 1 || x == 2) return 1; if (fd[x]) return fd[x]; return fd[x] = ((long long) Fibonacci(x - 1) + (long long) Fibonacci(x - 2)) % mod; } void PrimeFac(int x) { int sq = sqrt(x); for (int i = 2; i <= sq; i++) if (x % i == 0) { x /= i; pd[ptop] = i; ptop++; while (x % i == 0) { pd[ptop] = i; ptop++; x /= i; } } if (x > 1) pd[ptop] = x, ptop++; } int main() { scanf("%d", &n); int fb = Fibonacci(n); PrimeFac(fb); printf("%d=", fb); for (int i = 1; i < ptop; i++) { if (i > 1) printf("*"); printf("%d", pd[i]); } printf(" "); return 0; }
3. 树状数组
/* Fenwick Tree * Au: GG */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> using namespace std; const int N = 500000 + 3; int n, m, d[N]; inline int lowbit(int x) { return x & (-x); } inline void modify(int x, int val) { while (x <= n) { d[x] += val; x += lowbit(x); } } inline int getsum(int x) { int sum = 0; while (x > 0) { sum += d[x]; x -= lowbit(x); } return sum; } int main() { scanf("%d%d", &n, &m); for (int i = 1, w; i <= n; i++) { scanf("%d", &w); modify(i, w); } while (m--) { int o, x, y; scanf("%d%d%d", &o, &x, &y); if (o == 1) modify(x, y); if (o == 2) printf("%d ", getsum(y) - getsum(x - 1)); } return 0; }
4. 离散化
/* P2448 无尽的生命 * 树状数组 + 离散化 */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <cctype> #include <iostream> #include <algorithm> #define ll long long using namespace std; const int N = 100000 + 3; int n, m, a[2 * N], b[2 * N], h[2 * N], cnt; ll d[2 * N], ans; struct ques {int x, y;} q[N]; int readint() { int a = 0; char c = getchar(); while (!isdigit(c)) c = getchar(); while (isdigit(c)) { a = a * 10 + c - '0'; c = getchar(); } return a; } int find(int x) { int l = 1, r = m; while (l <= r) { int mid = (l + r) >> 1; if (h[mid] == x) return mid; else if (h[mid] < x) l = mid + 1; else r = mid - 1; } return r; } inline int lowbit(int x) { return x & (-x); } inline void modify(int x, int val) { while (x <= m) { d[x] += val; x += lowbit(x); } } inline ll getsum(int x) { ll sum = 0; while (x) { sum += d[x]; x -= lowbit(x); } return sum; } int main() { n = readint(); for (int i = 1; i <= n; i++) { a[++cnt] = q[i].x = readint(); a[++cnt] = q[i].y = readint(); } sort(a + 1, a + cnt + 1); for (int i = 1; i <= cnt; i++) if (a[i] != a[i - 1]) h[++m] = a[i]; for (int i = 1; i <= m; i++) b[i] = i; for (int i = 1; i <= n; i++) swap(b[find(q[i].x)], b[find(q[i].y)]); modify(b[m], 1); for (int i = m - 1; i; i--) { ll o = h[i + 1] - h[i] - 1; ll p = getsum(i); ans += o * p; modify(i, o); ans += getsum(b[i] - 1); modify(b[i], 1); } printf("%lld ", ans); return 0; }
/* 火柴排队 * Au: GG */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int N = 200000 + 3; const int MOD = 99999997; int n, c[N], d[N]; ll ans; struct node { int num, pos; bool operator < (const node &x) const { return num < x.num; } } a[N], b[N]; inline int lowbit(int x) { return x & (-x); } inline void modify(int x, int val) { while (x <= n) { d[x] += val; x += lowbit(x); } } inline ll query(int x) { ll sum = 0; while (x) { sum += d[x]; x -= lowbit(x); } return sum; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i].num), a[i].pos = i; for (int i = 1; i <= n; i++) scanf("%d", &b[i].num), b[i].pos = i; sort(a + 1, a + n + 1); sort(b + 1, b + n + 1); for (int i = 1; i <= n; i++) c[b[i].pos] = a[i].pos; for (int i = 1; i <= n; i++) { modify(c[i], 1); ans = (ans + i - query(c[i])) % MOD; } printf("%lld ", ans); return 0; }
5. 快速幂
/* P1226 取余运算||快速幂 * Au: GG */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #define ll long long using namespace std; int n, m, mod; ll quickpow(int a, int b) { ll k = a, tot = 1; while (b) { if (b & 1 == 1) tot = tot * k % mod; k = k * k % mod; b >>= 1; } return tot; } int main() { scanf("%d%d%d", &n, &m, &mod); printf("%d^%d mod %d=%lld ", n, m, mod, quickpow(n, m)); return 0; }
6. 归并排序 (Unaccepted)
7. 二分
/* P2678 跳石头 * Au: GG */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> using namespace std; const int N = 50000 + 3; int L, n, m, dis[N], ans; bool judge(int x) { int last = 0, cnt = 0; for (int i = 1; i <= n + 1; i++) { if (dis[i] - dis[last] < x) cnt++; else last = i; } if (cnt > m) return false; return true; } int main() { scanf("%d%d%d", &L, &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &dis[i]); dis[n + 1] = L; int l = 0, r = L, mid; while (l <= r) { mid = (l + r) >> 1; if (judge(mid)) l = mid + 1, ans = mid; else r = mid - 1; } printf("%d ", ans); return 0; }
/* P1462 通往奥格瑞玛的道路 * Au: GG */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <queue> #include <iostream> #include <algorithm> #define ll long long using namespace std; const int N = 10000 + 3, M = 50000 + 3; int n, m; ll d[N]; ll blood, f[N], w[M * 2], bin[N]; bool inq[N]; int head[N], nex[M * 2], to[M * 2], en; queue<int> q; void add(int x, int y, int z) { nex[++en] = head[x]; head[x] = en; to[en] = y; w[en] = z; nex[++en] = head[y]; head[y] = en; to[en] = x; w[en] = z; } bool judge(int fn) { memset(d, 0x7f, sizeof(d)); memset(inq, false, sizeof(inq)); for (int i = 1; i <= n; i++) if (f[i] > fn) inq[i] = true; if (f[1] > fn || f[n] > fn) return false; q.push(1); d[1] = 0; inq[1] = true; while (!q.empty()) { int a = q.front(); q.pop(); inq[a] = false; for (int b = head[a]; b; b = nex[b]) if (d[a] + w[b] < d[to[b]]) { d[to[b]] = d[a] + w[b]; if (!inq[to[b]]) { q.push(to[b]); inq[to[b]] = true; } } } return d[n] <= blood; } int main() { int a, b; ll c; scanf("%d%d%lld", &n, &m, &blood); for (int i = 1; i <= n; i++) { scanf("%lld", &f[i]); bin[i] = f[i]; } for (int i = 1; i <= m; i++) { scanf("%d%d%lld", &a, &b, &c); add(a, b, c); } sort(bin + 1, bin + n + 1); int l = 1, r = n, mid; while (l < r) { mid = (l + r) >> 1; if (judge(bin[mid])) r = mid; else l = mid + 1; } if (l == r && !judge(bin[l])) printf("AFK "); else printf("%d ", bin[l]); return 0; }