好久木有做题啦!
/* I will wait for you */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #include <iostream> #include <fstream> #include <vector> #include <queue> #include <deque> #include <set> #include <map> #include <string> #include <ext/pb_ds/priority_queue.hpp> #define fi first #define se second using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef map<int, int> mii; const int maxn = 500010; const int maxm = 1010; const int maxs = 26; const int inf = 0x3f3f3f3f; const int P = 1000000007; const double eps = 1e-6; inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : 1), ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * f; } struct query { int x, y, type; } e[maxn]; bool operator < (query a, query b) { return a.y > b.y; } int n, m, top, h[maxn], sta[maxn], sum_1[maxn], sum_2[maxn], dp[maxn]; __gnu_pbds::priority_queue<query> pri[maxn]; void init() { for (int i = 1; i <= n; i++) { pri[i].clear(), dp[i] = 0; sum_1[i] = sum_2[i] = 0; } } int main() { int T = read(), cnt = 0; while (T--) { n = read(), m = read(), init(); for (int i = 1; i <= n - 1; i++) h[i] = read(); h[0] = h[n] = inf; for (int i = 1; i <= m; i++) { int x = read(), y = read() + 1, t = read(); e[i] = (query) {x, y, t}; pri[x].push(e[i]), sum_2[x] += (t == 0); } top = sta[0] = 0; for (int i = 1; i <= n; i++) { while (h[i] > h[sta[top]]) { int cnt_1 = 0, cnt_2 = 0, hig = 0; int ans = sum_1[i] + sum_2[i], j = sta[top]; while (!pri[i].empty() && pri[i].top().y <= h[j]) { query tmp = pri[i].top(); pri[i].pop(); if (tmp.y != hig) { sum_1[i] += cnt_1, cnt_1 = 0; sum_2[i] -= cnt_2, cnt_2 = 0; ans = max(ans, sum_1[i] + sum_2[i]); hig = tmp.y; } cnt_1 += (tmp.type == 1); cnt_2 += (tmp.type == 0); } sum_1[i] += cnt_1, sum_2[i] -= cnt_2; ans = max(ans, sum_1[i] + sum_2[i]); dp[i] = max(dp[i], dp[j] + ans); sum_1[i] += sum_1[j], sum_2[i] += sum_2[j]; top -= 1, pri[i].join(pri[j]); } int cnt_1 = 0, cnt_2 = 0, hig = 0; int ans = sum_1[i] + sum_2[i], j = sta[top]; while (!pri[i].empty() && pri[i].top().y <= h[i]) { query tmp = pri[i].top(); pri[i].pop(); if (tmp.y != hig) { sum_1[i] += cnt_1, cnt_1 = 0; sum_2[i] -= cnt_2, cnt_2 = 0; ans = max(ans, sum_1[i] + sum_2[i]); hig = tmp.y; } cnt_1 += (tmp.type == 1); cnt_2 += (tmp.type == 0); } sum_1[i] += cnt_1, sum_2[i] -= cnt_2; ans = max(ans, sum_1[i] + sum_2[i]); dp[i] = max(dp[i], dp[j] + ans); sta[++top] = i; } printf("Case #%d: %d\n", ++cnt, dp[n]); } return 0; }