JOISC 2020 補題記錄

Day 1 和 Day 4 鴿了,Day 2 和 Day 3 打得像 ** 一樣。

Day 2 T3 簡單數數題拿到手就化了一堆奇怪的充要條件結果就只能 \O(n^4) dp 了,優化了很久(以爲我的充要條件很靠譜),留了 20min rush 沒寫完,遺憾離場。Day 3 T2 4K- 的 DS 題調了一個小時還沒調出來,遺憾離場。賽後 30min 才 AC

感覺這個 2020 年狀態一直不太行……經常浮躁而無法靜下來去分析一個問題試圖突破……希望,能改改吧。感覺在理論狀態下應該只有 D1T2 和 D4T2 兩個題切不掉的……但實際去考有沒有 175 + 200 + 205 + 200 都是個問題……

//先貼代碼,題解想起來再補 代碼也鴿了

D1T1

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

int n, a[1000005][2];
PII dp[1000005][2];

PII unite(const PII& u, const PII& v)
{
	if(u.first > u.second) return v;
	if(v.first > v.second) return u;
	return MP(min(u.first, v.first), max(u.second, v.second));
}

char ans[1000005];

int main()
{
	scanf("%d", &n);
	rep(i, 2) rep(j, 2 * n) scanf("%d", &a[j][i]);
	dp[0][0] = MP(0, 0);
	dp[0][1] = MP(1, 1);
	rep1(i, 2 * n - 1) {
		dp[i][0] = dp[i][1] = MP(0, -1);
		rep(j, 2) rep(k, 2) if(a[i - 1][k] <= a[i][j]) dp[i][j] = unite(dp[i][j], dp[i - 1][k]);
		dp[i][1].first ++;
		dp[i][1].second ++;
	}
	int ct = -1, cs = n;
	if(dp[2 * n - 1][0].first <= n && dp[2 * n - 1][0].second >= n) ct = 0;
	else if(dp[2 * n - 1][1].first <= n && dp[2 * n - 1][1].second >= n) ct = 1;
	if(ct == -1) {
		printf("-1\n");
		return 0;
	}
	for(int i = 2 * n - 1; i >= 0; i --) {
		cs -= ct;
		ans[i] = 'A' + ct;
		if(i == 0) break;
		int nt = -1;
		if(a[i - 1][0] <= a[i][ct] && dp[i - 1][0].first <= cs && dp[i - 1][0].second >= cs) nt = 0;
		else if(a[i - 1][1] <= a[i][ct] && dp[i - 1][1].first <= cs && dp[i - 1][1].second >= cs) nt = 1;
		ct = nt;
	}
	
	printf("%s\n", ans);
	return 0;
}

D1T2

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;

int n, k;
int del[200005];
int xl[200005], yl[200005], xr[200005], yr[200005];
int permx[200005], permy[200005];
int xa[200005], ya[200005];

int sta[200005];
void occupy(int cx, int cy, int ck)
{
	rep(i, n) {
		if(del[i]) continue;
		if(xl[i] <= cx && yl[i] <= cy && xr[i] >= cx && yr[i] >= cy) del[i] = ck;
	}
}
void disocc(int ck)
{
	rep(i, n) if(del[i] == ck) del[i] = 0;
}

bool s_trivial(int ck, int retx[], int rety[])
{
	int xlm = -INF, xrm = INF, ylm = -INF, yrm = INF;
	rep(i, n) {
		if(del[i]) continue;
		xlm = max(xlm, xl[i]);
		xrm = min(xrm, xr[i]);
		ylm = max(ylm, yl[i]);
		yrm = min(yrm, yr[i]);
	}
	if(xlm == -INF) return true;
	if(ck == 0) return false;
	if(xlm <= xrm) {
		int cnt = 0, cr = INF;
		for(int i = n - 1; i >= 0; i --) {
			int cur = permy[i];
			if(del[cur]) continue;
			if(cr > yr[cur]) {
				cr = yl[cur];
				retx[cnt] = xlm;
				rety[cnt] = cr;
				cnt ++;
			}
		}
		return cnt <= ck;
	} else if(ylm <= yrm) {
		int cnt = 0, cr = INF;
		for(int i = n - 1; i >= 0; i --) {
			int cur = permx[i];
			if(del[cur]) continue;
			if(cr > xr[cur]) {
				cr = xl[cur];
				retx[cnt] = cr;
				rety[cnt] = ylm;
				cnt ++;
			}
		}
		return cnt <= ck;
	} else if(ck == 1) return false;
	
	occupy(xlm, ylm, ck);
	retx[0] = xlm;
	rety[0] = ylm;
	if(s_trivial(ck - 1, retx + 1, rety + 1)) return true;
	disocc(ck);
	
	occupy(xlm, yrm, ck);
	retx[0] = xlm;
	rety[0] = yrm;
	if(s_trivial(ck - 1, retx + 1, rety + 1)) return true;
	disocc(ck);
	
	occupy(xrm, ylm, ck);
	retx[0] = xrm;
	rety[0] = ylm;
	if(s_trivial(ck - 1, retx + 1, rety + 1)) return true;
	disocc(ck);
	
	occupy(xrm, yrm, ck);
	retx[0] = xrm;
	rety[0] = yrm;
	if(s_trivial(ck - 1, retx + 1, rety + 1)) return true;
	disocc(ck);
	return false;
}

int xs[400005], ys[400005], xtot, ytot, ltot;
int rgl[4][200005], rgr[4][200005];
int ver[4][200005], vcnt;
vector<int> G[4000015];
bool vis[4000015]; 
int ret[2000015];

void add_edge(int x, int y, int vx, int vy)
{
	G[x << 1 | vx ^ 1].push_back(y << 1 | vy);
	G[y << 1 | vy ^ 1].push_back(x << 1 | vx);
}

void dfs(int v)
{
	vis[v] = true;
	rep(i, G[v].size()) if(!vis[G[v][i]]) dfs(G[v][i]);
	if(ret[v >> 1] == -1) ret[v >> 1] = !(v & 1);
}

void s_ntrivial()
{
	int xlm = -INF, xrm = INF, ylm = -INF, yrm = INF;
	rep(i, n) {
		xlm = max(xlm, xl[i]);
		xrm = min(xrm, xr[i]);
		ylm = max(ylm, yl[i]);
		yrm = min(yrm, yr[i]);
	}
	
	rep(i, n) {
		xs[2 * i] = xl[i];
		xs[2 * i + 1] = xr[i];
	}
	sort(xs, xs + 2 * n);
	xtot = unique(xs, xs + 2 * n) - xs;
	rep(i, n) {
		ys[2 * i] = yl[i];
		ys[2 * i + 1] = yr[i];
	}
	sort(ys, ys + 2 * n);
	ytot = unique(ys, ys + 2 * n) - ys;
	
	rep(i, 4) rep(j, n) rgl[i][j] = rgr[i][j] = -1;
	rep(i, n) {
		int lx = xl[i] <= xrm;
		int rx = xr[i] >= xlm;
		int ly = yl[i] <= yrm;
		int ry = yr[i] >= ylm; 
		if(lx + rx + ly + ry >= 3) continue;
		if(lx) {
			rgl[0][i] = lower_bound(ys, ys + ytot, max(yl[i], yrm)) - ys;
			rgr[0][i] = lower_bound(ys, ys + ytot, min(yr[i], ylm)) - ys;
		}
		if(rx) {
			rgl[1][i] = lower_bound(ys, ys + ytot, max(yl[i], yrm)) - ys;
			rgr[1][i] = lower_bound(ys, ys + ytot, min(yr[i], ylm)) - ys;
		}
		if(ly) {
			rgl[2][i] = lower_bound(xs, xs + xtot, max(xl[i], xrm)) - xs;
			rgr[2][i] = lower_bound(xs, xs + xtot, min(xr[i], xlm)) - xs;
		}
		if(ry) {
			rgl[3][i] = lower_bound(xs, xs + xtot, max(xl[i], xrm)) - xs;
			rgr[3][i] = lower_bound(xs, xs + xtot, min(xr[i], xlm)) - xs;
		}
	}
	
	ltot = max(xtot, ytot) + 1;
	vcnt = 4 * ltot;
	rep1(i, ytot) add_edge(i - 1, i, 1, 0);
	rep1(i, ytot) add_edge(ltot + i - 1, ltot + i, 1, 0);
	rep1(i, xtot) add_edge(ltot * 2 + i - 1, ltot * 2 + i, 1, 0);
	rep1(i, xtot) add_edge(ltot * 3 + i - 1, ltot * 3 + i, 1, 0);
	
	rep(i, n) {
		int p0, p1;
		for(p0 = 0; p0 < 4 && rgl[p0][i] == -1; p0 ++) ;
		for(p1 = 3; p1 >= 0 && rgl[p1][i] == -1; p1 --) ;
		if(p1 == -1) continue;
		
		ver[p0][i] = vcnt ++;
		if(p1 > p0) ver[p1][i] = vcnt ++;
		add_edge(ver[p0][i], p0 * ltot + rgl[p0][i], 1, 1);
		add_edge(ver[p0][i], p0 * ltot + rgr[p0][i] + 1, 1, 0);
		if(p0 != -1) {
			add_edge(ver[p1][i], p1 * ltot + rgl[p1][i], 1, 1);
			add_edge(ver[p1][i], p1 * ltot + rgr[p1][i] + 1, 1, 0);
		}
		add_edge(ver[p0][i], ver[p1][i], 0, 0);
	}
	
	rep(i, vcnt) ret[i] = -1;
	rep(i, vcnt * 2) if(!vis[i]) dfs(i);
	
	rep(i, ytot + 1) if(ret[i] || i == ytot) {
		xa[0] = xrm;
		ya[0] = ys[max(i - 1, 0)];
		break;
	}
	rep(i, ytot + 1) if(ret[i + ltot] || i == ytot) {
		xa[1] = xlm;
		ya[1] = ys[max(i - 1, 0)];
		break;
	}
	rep(i, xtot + 1) if(ret[i + ltot * 2] || i == xtot) {
		ya[2] = yrm;
		xa[2] = xs[max(i - 1, 0)];
		break;
	}
	rep(i, xtot + 1) if(ret[i + ltot * 3] || i == xtot) {
		ya[3] = ylm;
		xa[3] = xs[max(i - 1, 0)];
		break;
	}
}

template<int* arr>
bool cmp(int i, int j)
{
	return arr[i] < arr[j];
}

int main()
{
	scanf("%d%d", &n, &k);
	rep(i, n) scanf("%d%d%d%d", &xl[i], &yl[i], &xr[i], &yr[i]);
	
	rep(i, n) permx[i] = permy[i] = i;
	sort(permx, permx + n, cmp<xl>);
	sort(permy, permy + n, cmp<yl>);
	
	rep(i, n) xa[i] = ya[i] = 1;
	if(!s_trivial(k, xa, ya)) s_ntrivial();
	
	rep(i, k) printf("%d %d\n", xa[i], ya[i]);
	return 0;
}

D1T3

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

namespace s64
{
	int n, m, q;
	int x[500005], y[500005];
	int qt[1000005], qv[1000005];
	int px[500005], perm[500005], pos[500005];
	int ax[1000005], ay[1000005];
	
	bool cmpx(int i, int j)
	{
		return x[i] < x[j] || x[i] == x[j] && y[i] < y[j];
	}
	
	bool cmpy(int i, int j)
	{
		return i == -1 ? false : (j == -1 ? true : y[i] < y[j]);
	}
	
	struct segt
	{
		int dat[1048576];
		segt()
		{
			memset(dat, -1, sizeof(dat));
		}
		void build()
		{
			rep(i, m) dat[i + 524288] = perm[i];
			int l = 524288, r = m + 524287;
			l >>= 1; r >>= 1;
			while(l > 0) {
				for(int i = l; i <= r; i ++) dat[i] = cmpy(dat[i << 1], dat[i << 1 | 1]) ? dat[i << 1] : dat[i << 1 | 1];
				l >>= 1;
				r >>= 1;
			}
		}
		void erase(int cur)
		{
			cur = pos[cur] + 524288;
			dat[cur] = -1;
			for(cur >>= 1; cur > 0; cur >>= 1) dat[cur] = cmpy(dat[cur << 1], dat[cur << 1 | 1]) ? dat[cur << 1] : dat[cur << 1 | 1];
		}
		int query(int cx)
		{
			int l = 524288, r = upper_bound(px, px + m, cx) - px + 524287;
			int ret = -1;
			while(l < r) {
				if(l & 1) ret = cmpy(ret, dat[l]) ? ret : dat[l];
				if(!(r & 1)) ret = cmpy(ret, dat[r]) ? ret : dat[r];
				l = l + 1 >> 1;
				r = r - 1 >> 1;
			}
			if(l == r) ret = cmpy(ret, dat[l]) ? ret : dat[l];
			return ret;
		}
	}tre;
	
	struct dsu
	{
		int pre[500005];
		void init()
		{
			rep(i, m) pre[i] = i;
		}
		int root(int x)
		{
			return pre[x] == x ? x : pre[x] = root(pre[x]);
		}
	}con;
	
	bool del[500005];
	int tp[500005];
	set<int> hv, hvu, hvr;
	map<int, int> ver, hor;
	
	void insert_d(map<int, int>& cur, int cv, int cdat)
	{
		if(cur.find(cdat) == cur.end()) cur.insert(MP(cdat, cv));
		else con.pre[cv] = cur[cdat];
	}
	
	void solve()
	{
		rep(i, m) perm[i] = i;
		sort(perm, perm + m, cmpx);
		rep(i, m) pos[perm[i]] = i;
		rep(i, m) px[i] = x[perm[i]];
		tre.build();
		
		con.init();
		rep(i, m) del[i] = false;
		rep(i, m) tp[i] = -1;
		
		hv.clear();
		hvu.clear();
		hvr.clear();
		ver.clear();
		hor.clear();
		
		hv.insert(-1);
		hv.insert(n + 1);
		rep(i, q) {
			int pre, nxt;
			if(qt[i] == 2) {
				set<int>::iterator it = hv.lower_bound(qv[i]);
				nxt = *it;
				pre = *prev(it);
				while(true) {
					int cv = tre.query(qv[i]);
					if(cv == -1 || y[cv] > n - qv[i]) break;
					tre.erase(cv);
					tp[cv] = 0;
					insert_d(ver, cv, y[cv]);
				}
				if(ver.find(n - qv[i]) != ver.end()) {
					int cv = ver[n - qv[i]];
					del[cv] = true;
					ver.erase(n - qv[i]);
				}
				while(true) {
					map<int, int>::iterator it = hor.lower_bound(pre);
					if(it == hor.end() || it->first >= qv[i]) break;
					x[it->second] = qv[i];
					insert_d(hor, it->second, qv[i]);
					hor.erase(it);
				}
				map<int, int>::iterator it2 = hor.find(qv[i]);
				if(it2 != hor.end() && hvu.find(qv[i]) != hvu.end()) {
					del[it2->second] = true;
					hor.erase(it2);
				}
				hv.insert(qv[i]);
				hvr.insert(qv[i]);
			} else if(qt[i] == 3) {
				set<int>::iterator it = hv.upper_bound(qv[i]);
				nxt = *it;
				pre = *prev(it);
				while(true) {
					int cv = tre.query(qv[i]);
					if(cv == -1 || y[cv] > n - qv[i]) break;
					tre.erase(cv);
					tp[cv] = 1;
					insert_d(hor, cv, x[cv]);
				}
				if(hor.find(qv[i]) != hor.end()) {
					int cur = hor[qv[i]];
					del[cur] = true;
					hor.erase(qv[i]);
				}
				while(true) {
					map<int, int>::iterator it = ver.lower_bound(n - nxt);
					if(it == ver.end() || it->first >= n - qv[i]) break;
					y[it->second] = n - qv[i];
					insert_d(ver, it->second, n - qv[i]);
					ver.erase(it);
				}
				map<int, int>::iterator it2 = ver.find(n - qv[i]);
				if(it2 != ver.end() && hvr.find(qv[i]) != hvr.end()) {
					del[it2->second] = true;
					ver.erase(it2);
				}
				hv.insert(qv[i]);
				hvu.insert(qv[i]);
			} else {
				int cqv = con.root(qv[i]);
				if(tp[cqv] == -1) {
					ax[i] = x[cqv];
					ay[i] = y[cqv];
				} else if(tp[cqv]) {
					ax[i] = x[cqv];
					ay[i] = del[cqv] ? n - x[cqv] : n - *hv.upper_bound(x[cqv]);
				} else {
					ax[i] = del[cqv] ? n - y[cqv] : *prev(hv.lower_bound(n - y[cqv]));
					ay[i] = y[cqv];
				}
			}
		}
		
		rep(i, m) if(tp[i] == -1) tre.erase(i);
		
		rep(i, m) {
			if(tp[i] == -1) continue;
			int cqv = con.root(i);
			if(tp[cqv]) {
				x[i] = x[cqv];
				y[i] = del[cqv] ? n - x[cqv] : n - *hv.upper_bound(x[cqv]);
			} else {
				x[i] = del[cqv] ? n - y[cqv] : *prev(hv.lower_bound(n - y[cqv]));
				y[i] = y[cqv];
			}
		}
	}
}

int n, m, q;
int x[500005], y[500005];
int qt[1000005], qv[1000005], qw[1000005];
int ax[1000005], ay[1000005];
int vid[1000005], qid[1000005], vcnt;

void deposit(int l, int r)
{
	if(l == r) return;
	int mid = l + r >> 1;
	deposit(l, mid);
	deposit(mid + 1, r);
	
	int mv = -1;
	s64::m = 0;
	for(int i = l; i <= mid; i ++) {
		if(qt[i] != 4) continue;
		if(mv == -1) mv = vid[i];
		s64::x[s64::m] = qv[i];
		s64::y[s64::m] = qw[i];
		s64::m ++;
	}
	if(mv == -1) return;
	s64::q = 0;
	for(int i = mid + 1; i <= r; i ++) {
		if(qt[i] == 4 || qt[i] == 1 && (qv[i] < mv || qv[i] >= mv + s64::m)) continue;
		s64::qt[s64::q] = qt[i];
		s64::qv[s64::q] = qt[i] == 1 ? qv[i] - mv : qv[i];
		qid[i] = s64::q;
		s64::q ++;
	}
	s64::solve();
	for(int i = mid + 1; i <= r; i ++) if(qt[i] == 1 && qv[i] >= mv && qv[i] < mv + s64::m) {
		ax[i] = s64::ax[qid[i]];
		ay[i] = s64::ay[qid[i]];
	}
	
	s64::m = 0;
	for(int i = l; i <= mid; i ++) {
		if(qt[i] != 4) continue;
		qv[i] = s64::x[s64::m];
		qw[i] = s64::y[s64::m];
		s64::m ++;
	}
}

int main()
{
	scanf("%d%d%d", &n, &m, &q);
	rep(i, m) scanf("%d%d", &x[i], &y[i]);
	vcnt = m;
	rep(i, q) {
		scanf("%d%d", &qt[i], &qv[i]);
		if(qt[i] == 4) {
			scanf("%d", &qw[i]);
			vid[i] = vcnt ++;
		}
	}
	rep(i, q) if(qt[i] == 1) qv[i] --;
	else if(qt[i] == 2) qv[i] = n - qv[i];
	
	s64::n = n;
	s64::m = m;
	s64::q = 0;
	rep(i, m) {
		s64::x[i] = x[i];
		s64::y[i] = y[i];
	}
	rep(i, q) {
		if(qt[i] == 4 || qt[i] == 1 && qv[i] >= m) continue;
		s64::qt[s64::q] = qt[i];
		s64::qv[s64::q] = qv[i];
		qid[i] = s64::q;
		s64::q ++;
	}
	s64::solve();
	rep(i, q) if(qt[i] == 1 && qv[i] < m) {
		ax[i] = s64::ax[qid[i]];
		ay[i] = s64::ay[qid[i]];
	}
	
	deposit(0, q - 1);
	
	rep(i, q) if(qt[i] == 1) printf("%d %d\n", ax[i], ay[i]);
	return 0;
}

D2T1

#include "chameleon.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

int n;
vector<int> G[1005];
int rt[1005], xval[1005];
bool ban[1005][1005];

void add_edge(int u, int v)
{
	G[u].push_back(v);
	G[v].push_back(u);
	
	int nxv = xval[u] ^ xval[v] ^ 1;
	int cu = rt[u], cv = rt[v];
	rep1(i, 2 * n) if(rt[i] == cu) {
		rt[i] = cv;
		xval[i] ^= nxv;
	}
}

bool check(int x, int l, int r, int tp)
{
	vector<int> cq;
	cq.push_back(x);
	for(int i = l; i <= r; i ++)
	if(xval[i] == tp) cq.push_back(i);
	return Query(cq) + 1 <= cq.size();
}

bool check3(int a, int b, int c)
{
	vector<int> cq;
	cq.push_back(a);
	cq.push_back(b);
	cq.push_back(c);
	return Query(cq) == 1;
}

int query_pr(int x, int l, int r, int tp)
{
	if(l > r || !check(x, l, r, tp)) return -1;
	while(l < r) {
		int mid = l + r >> 1;
		if(check(x, mid + 1, r, tp)) l = mid + 1;
		else r = mid;
	}
	return r;
}

void Solve(int N)
{
	n = N;
	rep1(i, 2 * n) rep1(j, 2 * n) ban[i][j] = false;
	rep1(i, 2 * n) {
		rt[i] = i;
		xval[i] = 0;
	}
	rep1(i, 2 * n) {
		int cr = i - 1;
		vector<int> hv;
		while(true) {
			cr = query_pr(i, 1, cr, 0);
			if(cr == -1) break;
			hv.push_back(cr);
			cr --;
		}
		cr = i - 1;
		while(true) {
			cr = query_pr(i, 1, cr, 1);
			if(cr == -1) break;
			hv.push_back(cr);
			cr --;
		}
		rep(j, hv.size()) add_edge(i, hv[j]);
	}
	
	rep1(i, 2 * n) if(G[i].size() == 3) {
		if(check3(i, G[i][0], G[i][1])) ban[i][G[i][2]] = ban[G[i][2]][i] = true;
		else if(check3(i, G[i][0], G[i][2])) ban[i][G[i][1]] = ban[G[i][1]][i] = true;
		else ban[i][G[i][0]] = ban[G[i][0]][i] = true;
	}
	rep1(i, 2 * n) if(!xval[i])
	rep(j, G[i].size()) if(!ban[i][G[i][j]]) Answer(i, G[i][j]);
}

D2T2

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

int pre[100005], siz[100005];
int deg[100005], rdeg[100005];
set<int> G[100005], RG[100005], S[100005];
LL tot;

int root(int x)
{
	return pre[x] == x ? x : pre[x] = root(pre[x]);
}

void add_edge(int, int);
void merge(int u, int v)
{
	if(siz[u] < siz[v]) swap(u, v);
	pre[v] = u;
	vector<int> hv, rhv;
	for(set<int>::iterator it = G[v].begin(); it != G[v].end(); it ++) hv.push_back(*it);
	for(set<int>::iterator it = RG[v].begin(); it != RG[v].end(); it ++) rhv.push_back(*it);
	tot += 1LL * S[u].size() * siz[v];
	tot += 1LL * S[v].size() * siz[u];
	for(set<int>::iterator it = S[v].begin(); it != S[v].end(); it ++) {
		if(S[u].find(*it) != S[u].end()) tot -= siz[u] + siz[v];
		else S[u].insert(*it);
	}
	S[v].clear();
	siz[u] += siz[v];
	rep(i, hv.size()) {
		G[v].erase(hv[i]);
		RG[hv[i]].erase(v);
	}
	rep(i, rhv.size()) {
		RG[v].erase(rhv[i]);
		G[rhv[i]].erase(v);
	}
	rep(i, hv.size()) add_edge(u, hv[i]);
	rep(i, rhv.size()) add_edge(rhv[i], u);
}

void add_edge(int u, int v)
{
	u = root(u);
	v = root(v);
	if(u == v) return;
	if(G[u].find(v) != G[u].end()) return;
	if(G[v].find(u) != G[v].end()) {
		merge(u, v);
		return;
	}
	G[u].insert(v);
	RG[v].insert(u);
	deg[u] += siz[v];
	rdeg[v] += siz[u];
}

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	rep1(i, n) {
		pre[i] = i;
		siz[i] = 1;
	}
	rep1(i, n) S[i].insert(i);
	rep(i, m) {
		int u, v;
		scanf("%d%d", &u, &v);
		v = root(v);
		if(S[v].find(u) == S[v].end()) {
			S[v].insert(u);
			tot += siz[v];
		}
		add_edge(u, v);
		printf("%lld\n", tot);
	}
	return 0;
}

D2T3

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 1e9 + 7;

int n, a[605];
bool inq[1205]; 
int dp[1205][605];
int comb[1205][605], cdp[605][605], gtot[605];

int main()
{
	comb[0][0] = 1;
	rep(i, 1200) rep(j, 600) {
		comb[i + 1][j] = (comb[i + 1][j] + comb[i][j]) % MOD;
		comb[i + 1][j + 1] = (comb[i + 1][j + 1] + comb[i][j]) % MOD;
	}
	cdp[0][0] = 1;
	rep(i, 600) rep(j, 600) {
		cdp[i + 1][j + 1] = (cdp[i + 1][j + 1] + cdp[i][j]) % MOD;
		cdp[i + 1][j] = (cdp[i + 1][j] + 2LL * cdp[i][j]) % MOD;
		if(j > 0) cdp[i + 1][j - 1] = (cdp[i + 1][j - 1] + cdp[i][j]) % MOD;
	}
	gtot[0] = 1;
	rep1(i, 600) gtot[i] = 1LL * gtot[i - 1] * i % MOD;
	rep(i, 601) gtot[i] = 1LL * gtot[i] * cdp[i][0] % MOD; 
	for(int i = 600; i >= 1; i --) gtot[i] = 1LL * gtot[i - 1]  * (i + 1) % MOD;
	
	scanf("%d", &n);
	rep(i, n) scanf("%d", &a[i]);
	rep(i, n) inq[a[i]] = true;
	
	dp[2 * n][0] = 1;
	int ccnt = 0;
	for(int i = 2 * n; i >= 1; i --)
	if(!inq[i]) {
		rep(j, n + 1) {
			if(dp[i][j] == 0) continue;
			dp[i - 1][j] = (dp[i - 1][j] + 1LL * dp[i][j] * (j - ccnt)) % MOD;
		}
		ccnt ++;
	} else {
		rep(j, n + 1) {
			if(dp[i][j] == 0) continue;
			dp[i - 1][j] = (dp[i - 1][j] + dp[i][j]) % MOD;
			for(int k = j + 1; k <= n; k ++) dp[i - 1][k] = (dp[i - 1][k] +
			1LL * dp[i][j] * comb[2 * n - i - j - ccnt][k - j - 1] % MOD * gtot[k - j]) % MOD;
		}
	}
	
	int ans = dp[0][n];
	rep(i, n) ans = 1LL * ans * (MOD + 1) / 2 % MOD;
	printf("%d\n", ans);
	return 0;
}

D3T1

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;

struct segt
{
	LL dat[524288];
	void add(int l, int r, LL d)
	{
		l += 262144; r += 262144;
		while(l < r) {
			if(l & 1) dat[l] += d;
			if(!(r & 1)) dat[r] += d;
			l = l + 1 >> 1;
			r = r - 1 >> 1;
		}
		if(l == r) dat[l] += d;
	}
	LL query(int x)
	{
		LL ret = 0;
		for(x += 262144; x > 0; x >>= 1) ret += dat[x];
		return ret;
	}
}tre;

int n, a[200005];
int m, x[200005], y[200005], c[200005];
int par[200005];
int pre[200005][18];
vector<int> T[200005];
int dfn[200005], dfo[200005], tot;
vector<PII> qs[200005];
LL dp[200005];

int sta[100005], ssiz;
void gen_tre()
{
	ssiz = 1;
	sta[1] = -1;
	
	rep1(i, n) {
		while(a[sta[ssiz - 1]] < a[i]) ssiz --;
		if(sta[ssiz] != -1) par[sta[ssiz]] = i;
		par[i] = sta[ssiz - 1];
		sta[ssiz ++] = i;
		sta[ssiz] = -1;
	}
	rep1(i, n) pre[i][0] = par[i];
	rep1(i, 17) rep1(j, n) pre[j][i] = pre[pre[j][i - 1]][i - 1];
	rep1(i, n) T[par[i]].push_back(i);
}

int find_pre(int x, int y)
{
	for(int i = 17; i >= 0; i --) if(a[pre[x][i]] < y) x = pre[x][i];
	return x;
}

void dfs(int v)
{
	dfn[v] = tot ++;
	rep(i, T[v].size()) dfs(T[v][i]);
	dfo[v] = tot - 1;
}

void gen_dp(int v)
{
	rep(i, T[v].size()) {
		gen_dp(T[v][i]);
		dp[v] += dp[T[v][i]];
	}
	tre.add(dfn[v], dfn[v], dp[v]);
	rep(i, T[v].size()) {
		tre.add(dfn[v] + 1, dfn[T[v][i]] - 1, dp[T[v][i]]);
		tre.add(dfo[T[v][i]] + 1, dfo[v], dp[T[v][i]]);
	}
	rep(i, qs[v].size()) dp[v] = max(dp[v], tre.query(dfn[qs[v][i].first]) + qs[v][i].second);
}

int main()
{
	scanf("%d", &n);
	rep1(i, n) scanf("%d", &a[i]);
	a[0] = INF;
	gen_tre();
	
	scanf("%d", &m);
	LL ans = 0;
	rep(i, m) {
		scanf("%d%d%d", &x[i], &y[i], &c[i]);
		qs[find_pre(x[i], y[i])].push_back(MP(x[i], c[i]));
		ans += c[i];
	}
	dfs(0);
	gen_dp(0);
	ans -= dp[0];
	printf("%lld\n", ans);
	return 0;
}

D3T2

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

int n, m, l, c, q;
int a[200005], b[200005];
int pre[400005];
LL pdis[400005];

int ccnt;
bool inc[400005];
int cid[400005];
vector<int> hv[200005];
vector<int> T[400005];
int dfn[400005], dfo[400005], tot;
LL clen[200005];
LL dep[400005];

void dfs(int v, LL cd)
{
	cid[v] = ccnt;
	dep[v] = cd;
	dfn[v] = tot ++;
	rep(i, T[v].size()) {
		int u = T[v][i];
		dfs(u, cd + pdis[u]);
	}
	dfo[v] = tot - 1;
}

int deg[400005];
void gen_cyc()
{
	rep(i, n + m) deg[pre[i]] ++;
	queue<int> que;
	rep(i, n + m) if(deg[i] == 0) que.push(i);
	while(!que.empty()) {
		int v = que.front();
		que.pop();
		T[pre[v]].push_back(v);
		deg[pre[v]] --;
		if(deg[pre[v]] == 0) que.push(pre[v]);
	}
	rep(i, n + m) if(deg[i] != 0) {
		for(int j = i; deg[j] != 0; j = pre[j]) {
			inc[j] = true;
			hv[ccnt].push_back(j);
			deg[j] = 0;
		}
		for(int j = hv[ccnt].size() - 1; j >= 0; j --) {
			if(j != hv[ccnt].size() - 1) clen[ccnt] += pdis[hv[ccnt][j]];
			dfs(hv[ccnt][j], clen[ccnt]);
		}
		clen[ccnt] += pdis[hv[ccnt].back()];
		ccnt ++;
	}
}

int qv[200005];
LL qt[200005];
LL ans[200005]; 

vector<int> cs[200005];
vector<int> qs[200005];

bool cmpc(int c0, int c1)
{
	return dep[c0] < dep[c1] || dep[c0] == dep[c1] && c0 < c1;
}
bool cmpq(int q0, int q1)
{
	return dep[qv[q0]] + qt[q0] < dep[qv[q1]] + qt[q1] || dep[qv[q0]] + qt[q0] == dep[qv[q1]] + qt[q1] && q0 < q1;
}

int cc;
int tot1;
LL tot2;
struct fwt
{
	LL dat[524295];
	void add(int x, LL d)
	{
		for(; x <= 524288; x += x & -x) dat[x] += d;
	}
	LL query(int x)
	{
		LL ret = 0;
		for(; x > 0; x -= x & -x) ret += dat[x];
		return ret;
	}
} t3, t4;
vector<LL> rem;

void add_c(int x, int coef)
{
	tot1 += coef;
	tot2 += coef * (dep[x] / clen[cc]);
	t3.add(lower_bound(rem.begin(), rem.end(), dep[x] % clen[cc]) - rem.begin() + 1, coef);
	t4.add(dfn[x] + 1, coef);
}

LL query_q(int x, LL ct)
{
	if(!inc[x]) return t4.query(dfo[x] + 1) - t4.query(dfn[x]);
	LL ret = 0;
	ret += tot1 * (ct / clen[cc] + 1);
	ret -= tot2;
	ret -= tot1 - t3.query(upper_bound(rem.begin(), rem.end(), ct % clen[cc]) - rem.begin());
	ret -= t4.query(dfn[x]);
	return ret;
}

void solve_q(int id)
{
	cc = id;
	
	sort(cs[id].begin(), cs[id].end(), cmpc);
	sort(qs[id].begin(), qs[id].end(), cmpq);
	
	rem.clear();
	rep(i, cs[id].size()) rem.push_back(dep[cs[id][i]] % clen[cc]);
	sort(rem.begin(), rem.end());
	rem.resize(unique(rem.begin(), rem.end()) - rem.begin());
	
	int j = 0;
	rep(i, qs[id].size()) {
		while(j < cs[id].size() && dep[cs[id][j]] <= dep[qv[qs[id][i]]] + qt[qs[id][i]]) add_c(cs[id][j ++], 1);
		ans[qs[id][i]] = query_q(qv[qs[id][i]], dep[qv[qs[id][i]]] + qt[qs[id][i]]);
	}
	while(j > 0) add_c(cs[id][-- j], -1);
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &l, &c);
	rep(i, n) scanf("%d", &a[i]);
	rep(i, m) scanf("%d", &b[i]);
	rep(i, n) {
		int pos = upper_bound(a, a + n, a[i] - c % l) - a;
		pdis[i] = c - c % l;
		if(pos == 0) {
			pdis[i] += l;
			pos = upper_bound(a, a + n, a[i] + l - c % l) - a;
		}
		pre[i] = pos - 1;
		pdis[i] += a[i] - a[pos - 1];
	}
	rep(i, m) {
		int pos = upper_bound(a, a + n, b[i]) - a;
		pdis[i + n] = 0;
		if(pos == 0) {
			pdis[i + n] += l;
			pos = upper_bound(a, a + n, b[i] + l) - a;
		}
		pre[i + n] = pos - 1;
		pdis[i + n] += b[i] - a[pos - 1];
	}
	
	gen_cyc();

	scanf("%d", &q);
	rep(i, q) {
		scanf("%d%lld", &qv[i], &qt[i]);
		qv[i] --;
	}
	rep(i, q) qs[cid[qv[i]]].push_back(i);
	for(int i = n; i < n + m; i ++) cs[cid[i]].push_back(i);
	rep(i, ccnt) solve_q(i);
	rep(i, q) printf("%lld\n", ans[i]);
	return 0;
}

D3T3

Subtask 1 Anthony

#include "Anthony.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

vector<int> G[20005]; 
int dis[20005];
vector<int> Mark(int n, int m, int a, int b, vector<int> u, vector<int> v)
{
	rep(i, m) {
		G[u[i]].push_back(v[i]);
		G[v[i]].push_back(u[i]);
	}
	rep(i, n) dis[i] = -1;
	queue<int> que;
	que.push(0);
	dis[0] = 0;
	while(!que.empty()) {
		int v = que.front();
		que.pop();
		rep(i, G[v].size()) {
			int u = G[v][i];
			if(dis[u] != -1) continue;
			que.push(u);
			dis[u] = dis[v] + 1;
		}
	}
	vector<int> ret;
	rep(i, m) ret.push_back(min(dis[u[i]], dis[v[i]]) % 3);
	return ret;
}

Subtask 1 Catherine

#include "Catherine.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

void Init(int a, int b)
{
}

int Move(vector<int> y)
{
	vector<int> hv;
	rep(i, 3) if(y[i] != 0) hv.push_back(i);
	if(hv.size() == 1) return hv[0];
	else return hv[1] - hv[0] == 2 ? 2 : hv[0];
}

Subtask 2 Anthony

#include "Anthony.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

int dat[6] = {0, 0, 1, 1, 0, 1};

vector<PII> G[20005]; 
int ans[20005];

void dfs(int v, int par, int cd)
{
	rep(i, G[v].size())  {
		int u = G[v][i].first;
		if(u == par) continue;
		int nc = G[v].size() == 2 ? (cd + 1) % 6 : (dat[cd] ? 0 : 2);
		ans[G[v][i].second] = dat[nc];
		dfs(u, v, nc);
	}
}

vector<int> Mark(int n, int m, int a, int b, vector<int> u, vector<int> v)
{
	rep(i, m) {
		G[u[i]].push_back(MP(v[i], i));
		G[v[i]].push_back(MP(u[i], i));
	}
	dfs(0, -1, 0);
	vector<int> ret;
	rep(i, m) ret.push_back(ans[i]);
	return ret;
}

Subtask 2 Catherine

#include "Catherine.h"
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

const int dat[6] = {0, 0, 1, 1, 0, 1};
bool insm; 
int pre;
int sc[5], scnt; 

void Init(int a, int b)
{
	insm = true;
	pre = -1;
	scnt = 0;
}

int getone(vector<int> cc)
{
	return cc[0] ? 0 : 1;
}

int countt(vector<int> cc)
{
	return cc[0] + cc[1];
}

bool isdown()
{
	rep(i, 6) {
		bool ok = true;
		rep(j, 5) if(dat[(i + j) % 6] != sc[j]) ok = false;
		if(ok) return true;
	}
	return false;
}

int move_up(vector<int> cc)
{
	if(countt(cc) + (pre != -1) != 2) {
		if(cc[0] + (pre == 0) == 1) return pre == 0 ? -1 : (pre = 0);
		else return pre == 1 ? -1 : (pre = 1);
	} else return cc[1] ? (pre = 1) : (pre = 0);
}

int Move(vector<int> cur)
{
	if(countt(cur) + (pre != -1) != 2) insm = false;
	if(!insm) return move_up(cur);
	
	if(pre == -1) {
		sc[scnt ++] = getone(cur);
		cur[sc[0]] --;
	}
	sc[scnt ++] = getone(cur);
	if(scnt == 5) {
		insm = false;
		if(isdown()) return -1;
		else return move_up(cur);
	} else return pre = sc[scnt - 1];
}

D4T1

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;

int n, k, c[200005];
int occ[200005];
vector<int> G[200005];
vector<int> G0[200005];
bool del[200005];

int siz[200005];
void dfs0(int v, int par)
{
	siz[v] = 1;
	rep(i, G[v].size()) {
		int u = G[v][i];
		if(del[u] || u == par) continue;
		dfs0(u, v);
		siz[v] += siz[u];
	}
}

int cent(int v, int par, int csiz)
{
	rep(i, G[v].size()) {
		int u = G[v][i];
		if(del[u] || u == par) continue;
		if(siz[u] > csiz / 2) return cent(u, v, csiz);
	}
	return v;
}

int pre[200005], vis[200005];
bool inq[200005], ing[200005];
void dfs1(int v, int par, int cid)
{
	pre[v] = par;
	vis[v] = cid;
	inq[v] = false;
	ing[c[v]] = false;
	rep(i, G[v].size()) {
		int u = G[v][i];
		if(del[u] || u == par) continue;
		dfs1(u, v, cid);
	}
}

int tsolve(int v)
{
	dfs1(v, -1, v);
	int ret = 0;
	queue<int> que;
	inq[v] = true;
	que.push(v);
	while(!que.empty()) {
		int u = que.front();
		if(!ing[c[u]]) {
			ing[c[u]] = true;
			ret ++;
		}
		que.pop();
		rep(i, G0[u].size()) {
			int nu = G0[u][i];
			if(vis[nu] != v) return INF;
			while(!inq[nu]) {
				inq[nu] = true;
				que.push(nu);
				nu = pre[nu];
			}
		}
	}
	return ret;
}

int solve(int v)
{
	dfs0(v, -1);
	v = cent(v, -1, siz[v]);
	
	int ret = tsolve(v);
	
	del[v] = true;
	rep(i, G[v].size()) {
		int u = G[v][i];
		if(del[u]) continue;
		ret = min(ret, solve(u));
	}
	return ret;
}

int main()
{
	scanf("%d%d", &n, &k);
	rep(i, n - 1) {
		int u, v;
		scanf("%d%d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	rep1(i, n) {
		scanf("%d", &c[i]);
		if(occ[c[i]] != 0) {
			G0[occ[c[i]]].push_back(i);
			G0[i].push_back(occ[c[i]]);
		}
		occ[c[i]] = i;
	}
	
	printf("%d\n", solve(1) - 1);
	return 0;
}

D4T2

提答是不會碰的,這輩子都不會碰的

test 5 跑了 40min,屬實垃圾

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;

mt19937 rng(time(0));
int r, c;
char s[505][505];
int perm[1000005];
char cha[5] = "-|\\/";
int dx[4] = {0, -1, -1, -1}, dy[4] = {-1, 0, -1, 1};
int ret[505][505];
int occx[505][505], occy[505][505];

bool check(int i, int j, int k)
{
	return s[i][j] == 'W' && s[i - dx[k]][j - dy[k]] != 'W' && s[i + dx[k]][j + dy[k]] != 'W'
		&& s[i - dx[k]][j - dy[k]] != s[i + dx[k]][j + dy[k]];
}

void undo(int i, int j)
{
	if(occx[i][j] == -1) return;
	int ni = occx[i][j], nj = occy[i][j];
	occx[ni][nj] = occy[ni][nj] = -1;
	occx[ni - dx[ret[ni][nj]]][nj - dy[ret[ni][nj]]] = occy[ni - dx[ret[ni][nj]]][nj - dy[ret[ni][nj]]] = -1;
	occx[ni + dx[ret[ni][nj]]][nj + dy[ret[ni][nj]]] = occy[ni + dx[ret[ni][nj]]][nj + dy[ret[ni][nj]]] = -1;
	ret[ni][nj] = -1;
}

void endo(int i, int j, int k)
{
	occx[i][j] = occx[i - dx[k]][j - dy[k]] = occx[i + dx[k]][j + dy[k]] = i;
	occy[i][j] = occy[i - dx[k]][j - dy[k]] = occy[i + dx[k]][j + dy[k]] = j;
	ret[i][j] = k;
}

int cans = -1;
char ans[505][505];

int main()
{
	freopen("input_05.txt", "r", stdin);
	
	scanf("%d%d", &r, &c);
	rep(i, r) scanf("%s", s[i]);
	
	rep(i, 4 * r * c) perm[i] = i;
	
	rep(i, r) rep(j, c) {
		ret[i][j] = -1;
		occx[i][j] = occy[i][j] = -1;
	}
	
	rep(T, 100000) {
		shuffle(perm, perm + 4 * r * c, rng);
		rep(t, 4 * r * c) {
			int i = (t >> 2) / c, j = (t >> 2) % c, k = t & 3;
			if(i + dx[k] < 0 || i - dx[k] >= r) continue;
			if(j - dy[k] < 0 || j + dy[k] >= c || j + dy[k] < 0 || j - dy[k] >= c) continue;
			if(!check(i, j, k)) continue;
			int ccnt = (occx[i][j] != -1) + (occx[i + dx[k]][j + dy[k]] != -1) + (occx[i - dx[k]][j - dy[k]] != -1)
//			- (occx[i][j] == occx[i + dx[k]][j + dy[k]] && occy[i][j] == occy[i + dx[k]][j + dy[k]])
//			- (occx[i][j] == occx[i - dx[k]][j - dy[k]] && occy[i][j] == occy[i - dx[k]][j - dy[k]]);
;
			if(ccnt >= 2 && (rng() & 262143)) continue;
			if(ccnt == 1 && (rng() & 1)) continue;
			undo(i, j);
			undo(i + dx[k], j + dy[k]);
			undo(i - dx[k], j - dy[k]);
			endo(i, j, k);
		}
		
		int tot = 0;
		rep(i, r) rep(j, c) if(ret[i][j] != -1) tot ++;
		if(tot > cans) {
			fprintf(stderr, "new answer: %d\n", tot);
			cans = tot;
			rep(i, r) rep(j, c) ans[i][j] = ret[i][j] == -1 ? s[i][j] : cha[ret[i][j]];
			freopen("current2.txt", "w", stdout);
			rep(i, r) printf("%s\n", ans[i]);
			fclose(stdout);
			if(tot >= 48620) break;
		}
	}
	
	return 0;
}

D4T3

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const LL INF = 0x3f3f3f3f3f3f3f3f;

int n, m;
int t[100005], l[100005], r[100005], c[100005];
int cx[100005], cy[100005], qx[100005], qy[100005];
PII xval[100005];
LL dp[100005];
int del[100005];

int cmin(int i, int j)
{
	return (j == -1 || i != -1 && cy[i] < cy[j]) ? i : j;
}

struct segt
{
	int dat[262144];
	void build()
	{
		memset(dat, -1, sizeof(dat));
		rep(i, m) dat[131072 | cx[i]] = i;
		for(int i = 131071; i >= 0; i --) dat[i] = cmin(dat[i << 1], dat[i << 1 | 1]);
	}
	void erase(int x)
	{
		int id = 131072 | cx[x];
		dat[id] = -1;
		for(id >>= 1; id > 0; id >>= 1) dat[id] = cmin(dat[id << 1], dat[id << 1 | 1]);
	}
	int query(int x)
	{
		int l = 131072, r = 131072 | x;
		int ret = -1;
		while(l < r) {
			if(l & 1) ret = cmin(ret, dat[l]);
			if(!(r & 1)) ret = cmin(ret, dat[r]);
			l = l + 1 >> 1;
			r = r - 1 >> 1;
		}
		if(l == r) ret = cmin(ret, dat[l]);
		return ret;
	}
}tre;

int main()
{
	scanf("%d%d", &n, &m);
	rep(i, m) scanf("%d%d%d%d", &t[i], &l[i], &r[i], &c[i]);
	
	rep(i, m) {
		cx[i] = l[i] - t[i];
		cy[i] = l[i] + t[i];
		qx[i] = r[i] - t[i] + 1;
		qy[i] = r[i] + t[i] + 1;
	}
	rep(i, m) xval[i] = MP(cx[i], i);
	sort(xval, xval + m);
	rep(i, m) {
		cx[i] = lower_bound(xval, xval + m, MP(cx[i], i)) - xval;
		qx[i] = lower_bound(xval, xval + m, MP(qx[i], m)) - xval - 1;
	}
	
	rep(i, m) dp[i] = INF;
	LL ans = INF;
	
	tre.build();
	
	priority_queue<pair<LL, int> > que;
	rep(i, m) if(l[i] == 1) {
		dp[i] = c[i];
		que.push(MP(-dp[i], i));
		tre.erase(i);
	}
	
	while(!que.empty()) {
		int v = que.top().second;
		que.pop();
		if(r[v] == n) {
			printf("%lld\n", dp[v]);
			return 0;
		}
		while(true) {
			int i = tre.query(qx[v]);
			if(i == -1 || cy[i] > qy[v]) break;
			tre.erase(i);
			dp[i] = dp[v] + c[i];
			que.push(MP(-dp[i], i));
		}
	}
	
	printf("-1\n");
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章