zoukankan      html  css  js  c++  java
  • BZOJ3600:没有人的算术

    传送门
    如果能给每个 (pair) 按照权值编号就好了
    假设之前已经有了所有的权值的编号,现在考虑编号新的 (pair)
    如果看过了陈立杰的论文的话,不难得到一个重量平衡树的做法
    给树上每个子树一个实数权值区间 ([l,r]),这个点权值为 (mid=frac{l+r}{2})
    左子树 ([l,mid]) 右子树 ([mid,r])
    只需要选择一个树高 (log) 的树(treap/替罪羊树)使得满足精度要求即可

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn(5e5 + 5);
    const double alpha(0.75);
    
    int ls[maxn], rs[maxn], rt, tot, size[maxn], que[maxn], cnt, id[maxn], n, m;
    double val[maxn];
    pair <int, int> info[maxn];
    int mx[maxn << 2];
    
    inline int operator <(pair <int, int> a, pair <int, int> b) {
    	return val[a.first] == val[b.first] ? val[a.second] < val[b.second] : val[a.first] < val[b.first];
    }
    
    void Dfs(int u) {
    	if (!u) return;
    	Dfs(ls[u]), que[++cnt] = u, Dfs(rs[u]);
    }
    
    int Build(int l, int r, double vl, double vr) {
    	if (l > r) return 0;
    	double midv;
    	int mid, o;
    	mid = (l + r) >> 1, o = que[mid], midv = (vl + vr) * 0.5;
    	ls[o] = rs[o] = 0, val[o] = midv;
    	ls[o] = Build(l, mid - 1, vl, midv);
    	rs[o] = Build(mid + 1, r, midv, vr);
    	size[o] = size[ls[o]] + size[rs[o]] + 1;
    	return o;
    }
    
    int Rebuild(int x, double vl, double vr) {
    	cnt = 0, Dfs(x);
    	return Build(1, cnt, vl, vr);
    }
    
    int Insert(int &x, double vl, double vr, pair <int, int> v) {
    	double midv;
    	int ret;
    	midv = (vl + vr) * 0.5;
    	if (!x) {
    		x = ++tot, val[x] = midv, info[x] = v, size[x] = 1;
    		return x;
    	}
    	if (alpha * size[x] < max(size[ls[x]], size[rs[x]])) x = Rebuild(x, vl, vr);
    	if (v == info[x]) return x;
    	else if (v < info[x]) ret = Insert(ls[x], vl, midv, v);
    	else ret = Insert(rs[x], midv, vr, v);
    	size[x] = size[ls[x]] + size[rs[x]] + 1;
    	return ret;
    }
    
    void Modify(int x, int l, int r, int p) {
    	int mid;
    	if (l == r) mx[x] = l;
    	else {
    		mid = (l + r) >> 1;
    		p <= mid ? Modify(x << 1, l, mid, p) : Modify(x << 1 | 1, mid + 1, r, p);
    		mx[x] = val[id[mx[x << 1]]] >= val[id[mx[x << 1 | 1]]] ? mx[x << 1] : mx[x << 1 | 1];
    	}
    }
    
    int Query(int x, int l, int r, int ql, int qr) {
    	int mid, ret, v;
    	if (ql <= l && qr >= r) return mx[x];
    	mid = (l + r) >> 1, ret = -1, v;
    	if (ql <= mid) ret = Query(x << 1, l, mid, ql, qr);
    	if (qr > mid) {
    		v = Query(x << 1 | 1, mid + 1, r, ql, qr);
    		ret = (ret == -1 || val[id[v]] > val[id[ret]]) ? v : ret;
    	}
    	return ret;
    }
    
    int main() {
    	int i, l, r, k;
    	char op;
    	scanf("%d%d", &n, &m);
    	val[0] = -1, Insert(rt, 0, 1, make_pair(0, 0));
    	for (i = 1; i <= n; ++i) Modify(1, 1, n, i);
    	for (i = 1; i <= m; ++i) {
    		scanf(" %c%d%d", &op, &l, &r);
    		if (op == 'C') {
    			scanf("%d", &k);
    			id[k] = Insert(rt, 0, 1, make_pair(id[l], id[r]));
    			Modify(1, 1, n, k);
    		}
    		else printf("%d
    ", Query(1, 1, n, l, r));
    	}
        return 0;
    }
    
  • 相关阅读:
    java+opencv实现图像灰度化
    java实现高斯平滑
    hdu 3415 单调队列
    POJ 3368 Frequent values 线段树区间合并
    UVA 11795 Mega Man's Mission 状态DP
    UVA 11552 Fewest Flops DP
    UVA 10534 Wavio Sequence DP LIS
    UVA 1424 uvalive 4256 Salesmen 简单DP
    UVA 1099 uvalive 4794 Sharing Chocolate 状态DP
    UVA 1169uvalive 3983 Robotruck 单调队列优化DP
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10260000.html
Copyright © 2011-2022 走看看