某岛

… : "…アッカリ~ン . .. . " .. .
November 7, 2014

BZOJ 2527. [Poi2011]Meteors

Brief description:

给定一个长度为 M 的环,每个位置属于 N 个国家之一。
有 K 个事件依次进行。每个事件形如 l, r, d
表示环上的一段连续区间中,每个位置的数 +d 。。。
国家 i 希望自己所属区域的数的和 >= Pi。。
返回每个国家达到各自需求的时间。如果达不到输出 NIE。

Analysis:

cdq 分治。)

void cdq(const VI I, int l, int r)
// 表示确定 I 中的事件,哪些处在 [l, r) 的左半区间,哪些处在右半区间、递归处理。
// 先生效所有属于左半边的操作,此时可以判断每个事件的归属。。
// 之后需要先递归右半边,把操作复原后递归左半边、、否则需要用一个额外的容器记录增量。

。。。对时间二分。。整体处理询问。。



//}/* .................................................................................................................................. */

const int N = int(3e5) + 9;

VI L[N]; LL A[N]; int ans[N];
int n, m, k;

namespace BIT{
    typedef LL intt;
    intt C[N];

    void Add(int x, int d){
        for (;x<=n;x+=low_bit(x)) C[x] += d;
    }
    intt Sum(int x){
        intt z = 0; for (;x;x^=low_bit(x)) z += C[x];
        return z;
    }
    void Add(int l, int r, int d){
        Add(l, d); Add(r+1, -d);
    }
    void Init(){
        //fill(C+1, C+n+1, 0);
    }
} //using namespace BIT;


struct Op{
    int l, r, d;
    void in(){
        RD(l, r, d);
    }
    void Add(){
        if (l <= r) BIT::Add(l, r, d);
        else BIT::Add(l, n, d), BIT::Add(1, r, d);
    }
    void Del(){
        if (l <= r) BIT::Add(l, r, -d);
        else BIT::Add(l, n, -d), BIT::Add(1, r, -d);
    }

} op[N];


void cdq(const VI I, int l, int r){

    if (I.empty()) return;

    if (l + 1 == r){
        ECH(i, I) ans[*i] = l;
    }
    else{
        int m = l + r >> 1;
        FOR(i, l, m) op[i].Add();

        VI Il, Ir; ECH(i, I){

            LL a = 0; ECH(ii, L[*i]){
                a += BIT::Sum(*ii);
                if (a >= A[*i]) break;
            }

            if (a < A[*i]){
                Ir.PB(*i);
            }
            else{
                Il.PB(*i);
            }
        }

        cdq(Ir, m, r); FOR(i, l, m) op[i].Del();
        cdq(Il, l, m);
    }
}


int main(){

#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif

    RD(m, n); REP_1(i, n) L[RD()-1].PB(i);
    VI I; REP(i, m) RD(A[i]), I.PB(i);
    RD(k); REP(i, k) op[i].in();

    cdq(I, 0, k+1);

    REP(i, m){
        if (ans[i] == k) puts("NIE");
        else OT(ans[i]+1);
    }
}

http://www.lydsy.com/JudgeOnline/problem.php?id=2527
http://main.edu.pl/en/archive/oi/18/met

References:

http://www.cnblogs.com/zig-zag/archive/2013/04/29/3051212.html