2015上海区域赛D题 左偏树+树形DP

花费大约半星期时间终于做出来了. 这道题细节很多. 注释和思路之类的之后补充,现在太累辣!

题目链接:点击打开链接

代码如下:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define rep(i, n) for(int i=0; i 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

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> 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(); } }


你可能感兴趣的:(ACM,数据结构)