• 【LG3527】[POI2011]MET-Meteors


    【LG3527】[POI2011]MET-Meteors

    题面

    洛谷

    题解

    整体二分。

    每次二分(mid),如果到时间(mid)以收集过(P_i)就存入子序列(L),否则存入子序列(R)

    修改可以树状数组区间修改单点查询做

    每个王国的掉落地点用(vector)存一下即可

    看起来复杂度是平方的实则为线性的

    总复杂度(O(nlog^2))

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector> 
    using namespace std;
    namespace IO { 
        const int BUFSIZE = 1 << 20; 
        char ibuf[BUFSIZE], *is = ibuf, *it = ibuf; 
        inline char gc() { 
            if (is == it) it = (is = ibuf) + fread(ibuf, 1, BUFSIZE, stdin); 
    		return *is++; 
        } 
    } 
    inline int gi() {
        register int data = 0, w = 1;
        register char ch = 0;
        while (ch != '-' && (ch > '9' || ch < '0')) ch = IO::gc();
        if (ch == '-') w = -1 , ch = IO::gc();
        while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = IO::gc();
        return w * data;
    } 
    typedef long long ll; 
    const int MAX_N = 300005; 
    struct Node { ll p; int id; } q[MAX_N], lq[MAX_N], rq[MAX_N]; 
    struct Option { int l, r, v; } p[MAX_N]; 
    vector<int> G[MAX_N]; 
    int N, M, K, ans[MAX_N]; 
    ll c[MAX_N]; 
    inline int lb(int x) { return x & -x; } 
    void add(int x, int v) { while (x <= M) c[x] += v, x += lb(x); } 
    ll sum(int x) { ll res = 0; while (x > 0) res += c[x], x -= lb(x); return res; } 
    void modify(int x, int w) { 
        int l = p[x].l, r = p[x].r, v = p[x].v; 
        if (l <= r) add(l, w * v), add(r + 1, -w * v); 
        else add(1, v * w), add(r + 1, -v * w), add(l, v * w); 
    } 
    void Div(int lval, int rval, int st, int ed) { 
    	if (st > ed) return ; 
    	if (lval == rval) { for (int i = st; i <= ed; i++) ans[q[i].id] = lval; return ; } 
    	int mid = (lval + rval) >> 1; 
    	int lt = 0, rt = 0; ll res = 0; 
    	for (int i = lval; i <= mid; i++) modify(i, 1); 
    	for (int i = st; i <= ed; i++) { 
    	    res = 0; vector<int> :: iterator ite; int x = q[i].id; 
    	    for (ite = G[x].begin(); ite != G[x].end(); ++ite) { res += sum(*ite); if (res >= q[i].p) break; }
            if (res >= q[i].p) lq[++lt] = q[i]; 
    	    else q[i].p -= res, rq[++rt] = q[i]; 
        } 
        for (int i = lval; i <= mid; i++) modify(i, -1); 
        for (int i = 1; i <= lt; i++) q[st + i - 1] = lq[i]; 
        for (int i = 1; i <= rt; i++) q[st + lt + i - 1] = rq[i]; 
        Div(lval, mid, st, st + lt - 1); 
        Div(mid + 1, rval, st + lt, ed); 
    } 
    int main () { 
        N = gi(), M = gi(); 
        for (int i = 1; i <= M; i++) G[gi()].push_back(i); 
        for (int i = 1; i <= N; i++) q[i] = (Node){gi(), i}; 
        K = gi(); 
        for (int i = 1; i <= K; i++) p[i] = (Option){gi(), gi(), gi()}; 
        ++K; p[K] = (Option){1, M, 1e9}; 
        Div(1, K, 1, N); 
        for (int i = 1; i <= N; i++) ans[i] == K ? puts("NIE") : printf("%d
    ", ans[i]); 
        return 0; 
    } 
    
  • 相关阅读:
    LintCode "Maximum Gap"
    LintCode "Wood Cut"
    LintCode "Expression Evaluation"
    LintCode "Find Peak Element II"
    LintCode "Remove Node in Binary Search Tree"
    LintCode "Delete Digits"
    LintCode "Binary Representation"
    LeetCode "Game of Life"
    LintCode "Coins in a Line"
    LintCode "Word Break"
  • 原文地址:https://www.cnblogs.com/heyujun/p/10121988.html
Copyright © 2020-2023  润新知