zoukankan      html  css  js  c++  java
  • UOJ#414. 【APIO2018】新家

    传送门
    首先二分答案 (mid),问题变成求区间 ([l-mid,r+mid]) 在该年份的不同类型个数为 (k)
    关于年份的限制可以离线下来
    现在的问题就是区间数颜色,一个套路就是维护每个颜色的后继,即这个位置颜色的下一个位置
    那么,如果有 ((-infty,l-mid-1]) 的某一个值大于 (r+mid) 就不合法
    这个可以在线段树上二分实现
    时间复杂度 (nlogn)

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    namespace IO {
    	const int maxn(1 << 21 | 1);
    
    	char obuf[maxn], ibuf[maxn], *iS, *iT, c, *oS = obuf, *oT = obuf + maxn - 1, st[60];
    	int f, tp;
    	
    	inline char Getc() {
    		return iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, maxn, stdin), (iS == iT ? EOF : *iS++)) : *iS++;
    	}
    
    	template <class Int> inline void In(Int &x) {
    		for (c = Getc(), f = 1; c < '0' || c > '9'; c = Getc()) f = c == '-' ? -1 : 1;
    		for (x = 0; c >= '0' && c <= '9'; c = Getc()) x = (x << 1) + (x << 3) + (c ^ 48);
    		x *= f;
    	}
    
    	inline void Flush() {
    		fwrite(obuf, 1, oS - obuf, stdout);
    		oS = obuf;
    	}
    
    	inline void Putc(char c) {
    		*oS++ = c;
    		if (oS == oT) Flush();
    	}
    
    	template <class Int> inline void Out(Int x) {
    		if (x < 0) Putc('-'), x = -x;
    		if (!x) Putc('0');
    		while (x) st[++tp] = x % 10 + '0', x /= 10;
    		while (tp) Putc(st[tp--]);
    	}
    }
    
    using IO :: In;
    using IO :: Out;
    using IO :: Putc;
    using IO :: Flush;
    
    const int maxn(3e5 + 5);
    const int inf(1e9);
    
    int n, q, k, rt, tot, type, vis[maxn], ans[maxn];
    multiset <int> pos[maxn], heap[maxn * 20];
    multiset <int> :: iterator it, ot, at;
    
    struct Segment {
    	int ls, rs, mx, vmx;
    } tr[maxn * 20];
    
    struct Store {
    	int tp, x, tim, op;
    
    	inline bool operator <(Store b) const {
    		return tim < b.tim;
    	}
    } str[maxn << 1];
    
    struct Qry {
    	int x, tim, id;
    
    	inline bool operator <(Qry b) const {
    		return tim < b.tim;
    	}
    } qry[maxn];
    
    void Modify(int &x, int l, int r, int p, int v, int op) {
    	int mid;
    	if (!x) x = ++tot;
    	if (l == r) {
    		if (op == 1) heap[x].insert(v);
    		else heap[x].erase(heap[x].find(v));
    		at = heap[x].end();
    		tr[x].mx = heap[x].size() ? (*--at) : -inf;
    		tr[x].vmx = tr[x].mx + l;
    		return;
    	}
    	mid = (l + r) % 2 == 0 ? (l + r) / 2 : (l + r - 1) / 2;
    	p <= mid ? Modify(tr[x].ls, l, mid, p, v, op) : Modify(tr[x].rs, mid + 1, r, p, v, op);
    	tr[x].mx = max(tr[tr[x].ls].mx, tr[tr[x].rs].mx);
    	tr[x].vmx = max(tr[tr[x].ls].vmx, tr[x].mx + r);
    }
    
    int Query(int x, int l, int r, int ql, int qr) {
    	int mid, ret;
    	if (ql > qr) return inf;
    	if (!x || (ql <= l && qr >= r)) return tr[x].mx;
    	ret = -inf, mid = (l + r) >> 1;
    	if (ql <= mid) ret = Query(tr[x].ls, l, mid, ql, qr);
    	if (qr > mid) ret = max(ret, Query(tr[x].rs, mid + 1, r, ql, qr));
    	return ret;
    }
    
    int main() {
    	freopen("a.in", "r", stdin);
    	int cnt, i, j, x, t, a, b, mx, l, r, mid, cur, nmx, tmp, vmx;
    	In(n), In(k), In(q), cnt = mx = 0;
    	for (i = 1; i <= n; ++i) {
    		In(x), In(t), In(a), In(b);
    		str[++cnt] = (Store){t, x, a, 1};
    		str[++cnt] = (Store){t, x, b + 1, -1};
    		mx = max(mx, x);
    	}
    	sort(str + 1, str + cnt + 1);
    	for (i = 1; i <= q; ++i) {
    		In(qry[i].x), In(qry[i].tim);
    		qry[i].id = i, mx = max(mx, qry[i].x);
    	}
    	sort(qry + 1, qry + q + 1), tr[0].vmx = tr[0].mx = -inf;
    	for (i = 1; i <= k; ++i) pos[i].insert(-mx), pos[i].insert(inf), Modify(rt, -mx, mx, -mx, inf, 1);
    	for (i = 1, j = 1; i <= q; ++i) {
    		while (j <= cnt && str[j].tim <= qry[i].tim) {
    			if (str[j].op == 1) {
    				type += (vis[str[j].tp] == 0), ++vis[str[j].tp];
    				ot = it = pos[str[j].tp].insert(str[j].x);
    				--it, ++ot;
    				Modify(rt, -mx, mx, *it, *ot, -1);
    				Modify(rt, -mx, mx, *it, str[j].x, 1);
    				Modify(rt, -mx, mx, str[j].x, *ot, 1);
    			}
    			else {
    				type -= (vis[str[j].tp] == 1), --vis[str[j].tp];
    				ot = it = pos[str[j].tp].find(str[j].x);
    				--it, ++ot;
    				Modify(rt, -mx, mx, *it, *ot, 1);
    				Modify(rt, -mx, mx, *it, str[j].x, -1);
    				Modify(rt, -mx, mx, str[j].x, *ot, -1), ++it, pos[str[j].tp].erase(it);
    			}
    			++j;
    		}
    		if (type != k) ans[qry[i].id] = -1;
    		else {
    			l = -mx, r = mx, cur = rt, vmx = nmx = -inf;
    			while (l < r) {
    				mid = (l + r) >> 1;
    				tmp = max(nmx + mid, tr[tr[cur].ls].vmx);
    				if (tmp >= qry[i].x + qry[i].x || qry[i].x <= mid + 1) cur = tr[cur].ls, r = mid;
    				else vmx = tmp, nmx = max(nmx, tr[tr[cur].ls].mx), cur = tr[cur].rs, l = mid + 1;
    			}
    			if (Query(rt, -mx, mx, -mx, l) + l >= qry[i].x + qry[i].x) --l;
    			ans[qry[i].id] = qry[i].x - l - 1;
    		}
    	}
    	for (i = 1; i <= q; ++i) Out(ans[i]), Putc('
    ');
        return Flush(), 0;
    }
    
  • 相关阅读:
    HDOJ 3547 DIY Cube 解题报告
    一些经典的期望问题

    人生
    BZOJ 4341 [CF253 Printer] 解题报告
    BZOJ 4302 Buildings 解题报告
    OI 回忆录
    PyQt实现测试工具
    PyQt:eg4
    pyQt: eg3
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10253473.html
Copyright © 2011-2022 走看看