zoukankan      html  css  js  c++  java
  • bzoj5541

    线段树套set+最短路

    问题在于一次更新的点太多,如果按点扫描复杂度太高

    发现一次更新的边是一样的,按边跑最短路,一个点被访问就删除,每次矩形查询用线段树套$set$

    均摊复杂度$O(nlog^2n)$

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 5;
    int n, m, w, h;
    int t[maxn], d[maxn], x[maxn], y[maxn], p[maxn], L[maxn], R[maxn], U[maxn], D[maxn], vis[maxn];
    vector<int> G[maxn];
    priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
    set<pair<int, int> > s[maxn * 2];
    void update(int l, int r, int x, int p,  int id) {
        s[x].insert(make_pair(y[id], id));
        if(l == r) {
            return;
        }
        int mid = l + r >> 1;
        if(p <= mid) {
            update(l, mid, x << 1, p, id);
        } else {
            update(mid + 1, r, x << 1 | 1, p, id);
        }
    }
    void del(int l, int r, int x, int id, int val) {
        if(l > R[id] || r < L[id]) {
            return;
        }
        if(l >= L[id] && r <= R[id]) {
            set<pair<int, int> > :: iterator it = s[x].lower_bound(make_pair(D[id], 0)), tmp;
            while((it != s[x].end()) && (it -> first <= U[id])) {
                int u = it -> second;
                if(!vis[u]) {
                    vis[u] = 1;
                    d[u] = val;
                    for(int i = 0; i < G[u].size(); ++i) {
                        q.push(make_pair(d[u] + t[G[u][i]], G[u][i]));
                    }
                }
                tmp = it;
                ++it;
                s[x].erase(tmp);
            }
            return;
        }
        int mid = l + r >> 1;
        del(l, mid, x << 1, id, val);
        del(mid + 1, r, x << 1 | 1, id, val);
    }
    int main() {
        scanf("%d%d%d%d", &n, &m, &w, &h);
        for(int i = 0; i < n; ++i) {
            scanf("%d%d", &x[i], &y[i]);
            update(1, w, 1, x[i], i);
        }
        for(int i = 0; i < m; ++i) {
            scanf("%d%d%d%d%d%d", &p[i], &t[i], &L[i], &R[i], &D[i], &U[i]);
            --p[i];
            G[p[i]].push_back(i);
        }
        for(int i = 0; i < G[0].size(); ++i) {
            q.push(make_pair(t[G[0][i]], G[0][i]));
        }
        while(!q.empty()) {
            pair<int, int> o = q.top();
            q.pop();
            del(1, w, 1, o.second, o.first);
        }
        for(int i = 1; i < n; ++i) {
            printf("%d
    ", d[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    机器学习-决策树
    第八章- 假设检验
    第七章-参数估计
    第六章-总体与样本
    第五章-大数定律&中心极限定理
    第三,四章-多维随机变量及其分布
    第二章-随机变量分布
    第一章, 随机事件
    第六章-二次型
    第五章-矩阵的特征值和特征向量
  • 原文地址:https://www.cnblogs.com/19992147orz/p/11979677.html
Copyright © 2011-2022 走看看