花費大約半星期時間終於做出來了. 這道題細節很多. 註釋和思路之類的之後補充,現在太累辣!
題目鏈接:點擊打開鏈接
代碼如下:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<iomanip>
#include<stdlib.h>
#include<cstdio>
#include<string>
#include<string.h>
#include<set>
#include<stack>
#include<map>
using namespace std;
#define rep(i, n) for(int i=0; i<n ;i++)
#define Rep(i, n) for(int i=1; i<=n; i++)
#define SYS system("pause");
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x7fffffff;
const int MAX_N = 2e5 + 5;
const int MAX_V = 0;
const int MAX_M = 0;
const int MAX_Q = 0;
int l[MAX_N], r[MAX_N], dist[MAX_N];
int N, M;
P query[MAX_N], ban[MAX_N];
int par[MAX_N], in[MAX_N];
vector<P> s;
int merge(int a, int b) {
if (!a) return b;
if (!b) return a;
if (query[a].first > query[b].first) swap(a, b);
r[a] = merge(r[a], b);
if (dist[r[a]] > dist[l[a]]) swap(l[a], r[a]);
if (!r[a]) dist[a] = 0;
else dist[a] = dist[r[a]] + 1;
return a;
}
struct node {
int qe, h, out, in;
}nd[MAX_N];
int root(int x) {
return par[x] == x ? x : par[x] = root(par[x]);
}
void init() {
memset(l, 0, sizeof l);
memset(r, 0, sizeof r);
memset(dist, 0, sizeof dist);
Rep(i, N) {
par[i] = i;
nd[i].h = nd[i].in = nd[i].out = nd[i].qe = 0;
}
Rep(i, M) nd[in[i]].qe = merge(nd[in[i]].qe, i);
}
void get_up(int id, int he) {
int in_max=0, out_max=0, tmp = 0;
s.clear();
while (nd[id].qe && query[nd[id].qe].first < he) {
if (query[nd[id].qe].second == 0) in_max++;
s.push_back(query[nd[id].qe]);
nd[id].qe = merge(l[nd[id].qe], r[nd[id].qe]);
}
tmp = out_max = in_max;
for (int i = 0; i < s.size(); i++) {
if (i && s[i].first != s[i - 1].first) {
out_max = max(tmp, out_max);
}
s[i].second == 0 ? tmp-- : tmp++;
}
out_max = max(out_max, tmp);
nd[id].in = max(nd[id].in + in_max, nd[id].out + out_max);
nd[id].out += tmp;
nd[id].h = he;
}
void Merge(int p1, int p2, int he) {
p1 = root(p1);
p2 = root(p2);
if(nd[p1].h<he)get_up(p1, he);
if(nd[p2].h<he)get_up(p2, he);
nd[p1].qe = merge(nd[p1].qe, nd[p2].qe);
par[p2] = p1;
nd[p1].in = nd[p1].in + nd[p2].in;
nd[p1].out = nd[p1].out + nd[p2].out;
}
void solve() {
init();
sort(ban + 1, ban + N);
Rep(i, N - 1) {
Merge(ban[i].second, ban[i].second + 1, ban[i].first);
}
int final = root(1);
get_up(final, 1e9 + 7);
cout << nd[final].in << endl;
}
int main() {
int T,Case=0; cin >> T;
while (T--) {
cin >> N >> M;
Rep(i, N - 1) {
scanf("%d", &ban[i].first);
ban[i].second = i;
}
Rep(i, M) {
scanf("%d%d%d", &in[i], &query[i].first, &query[i].second);
}
cout << "Case #" << ++Case << ": ";
solve();
}
}