1 solutions
-
0
签到题,不用劳什子线段树,用 STL 就行了,但是常数会大一点,可能需要在 I/O 速度上找补一下。
#include <stdio.h> #include <set> #include <algorithm> #include <chrono> #include <random> using namespace std; inline int rd() { int k = 0; char c = getchar(); while (c < '0' || c > '9') c = getchar(); while (c >= '0' && c <= '9') k = (k << 1) + (k << 3) + (c ^ '0'), c = getchar(); return k; } const int N = 100010; int n, k; int a[N]; struct info { pair<int, int> cal, ori; bool operator<(const info& o) const { return (cal == o.cal) ? (ori < o.ori) : (cal < o.cal); } }; set<int> A; set<info> sum; inline void remove_A(int x) { if ((A.find(x) != A.begin()) && (A.upper_bound(x) != A.end())) { set<int>::iterator nxt = A.upper_bound(x), pre = --A.lower_bound(x); sum.erase({make_pair(*nxt - x, *nxt + x), make_pair(x, *nxt)}); sum.erase({make_pair(x - *pre, x + *pre), make_pair(*pre, x)}); sum.insert({make_pair(*nxt - *pre, *nxt + *pre), make_pair(*pre, *nxt)}); } else if (A.find(x) != A.begin()) { set<int>::iterator pre = --A.lower_bound(x); sum.erase({make_pair(x - *pre, x + *pre), make_pair(*pre, x)}); } else if (A.upper_bound(x) != A.end()) { set<int>::iterator nxt = A.upper_bound(x); sum.erase({make_pair(*nxt - x, *nxt + x), make_pair(x, *nxt)}); } A.erase(x); } inline void insert_A(int x) { if (A.count(x)) return; A.insert(x); if ((A.find(x) != A.begin()) && (A.upper_bound(x) != A.end())) { set<int>::iterator nxt = A.upper_bound(x), pre = --A.lower_bound(x); sum.insert({make_pair(*nxt - x, *nxt + x), make_pair(x, *nxt)}); sum.insert({make_pair(x - *pre, x + *pre), make_pair(*pre, x)}); sum.erase({make_pair(*nxt - *pre, *nxt + *pre), make_pair(*pre, *nxt)}); } else if (A.find(x) != A.begin()) { set<int>::iterator pre = --A.lower_bound(x); sum.insert({make_pair(x - *pre, x + *pre), make_pair(*pre, x)}); } else if (A.upper_bound(x) != A.end()) { set<int>::iterator nxt = A.upper_bound(x); sum.insert({make_pair(*nxt - x, *nxt + x), make_pair(x, *nxt)}); } } int main() { n = rd(), k = rd(); for (int i = 1; i <= n; ++i) a[i] = rd(); sort(a + 1, a + n + 1); for (int i = 1; i <= n; ++i) A.insert(a[i]); for (int i = 1; i < n; ++i) sum.insert({make_pair(a[i + 1] - a[i], a[i + 1] + a[i]), make_pair(a[i], a[i + 1])}); int loop = 0; while (A.size() > 1) { info tmp = *sum.begin(); sum.erase(sum.begin()), ++loop; remove_A(tmp.ori.first), remove_A(tmp.ori.second); int z = (tmp.ori.first + tmp.ori.second) % k; insert_A(z); } printf("%d\n%d", loop, *A.begin()); }
Information
- ID
- 36
- Time
- 1000ms
- Memory
- 512MiB
- Difficulty
- 2
- Tags
- # Submissions
- 3
- Accepted
- 1
- Uploaded By