码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 3262] 陌上花开 分治

时间:2017-07-28 19:20:59      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:==   algo   ring   实现   ons   ati   二维   algorithm   bzoj   

题意

  给定三个序列 $S = \left\{ s_1, s_2, ..., s_n \right\}$ , $C = \left\{ c_1, c_2, ..., c_n \right\}$ , $M = \left\{ m_1, m_2, ..., m_n \right\}$ .

  对任意 $i$ , 求 $level_i = \sum_{j \ne i, 1 \le j \le n}[s_i \ge s_j][c_i \ge c_j][m_i \ge m_j]$ .

 

分析

  宏观上, 将第一维按照 $s$ 排序, 那么只有前面的会对后面产生贡献. 分治, 考虑前面对后面的贡献.

  第二维考虑 排序 + two pointer , 第三维用树状数组.

 

  但是发现可能后面对前面贡献.

  为了特殊情况尽可能少, 我们按照三元组 $(s_i, c_i, m_i)$ 排序.

  还有一种特殊情况: 相等. 处理一下就好了.

 

 

实现

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <algorithm>
using namespace std;

#define F(i, a, b) for (register int i = (a); i <= (b); i++)

const int N = 100005;
const int K = 200005;

int n, k;
struct Data {
    int s, c, m, id;
    inline Data(int _s = 0, int _c = 0, int _m = 0, int _id = 0): s(_s), c(_c), m(_m), id(_id) {}
    friend inline bool operator < (Data A, Data B) {
        return A.s != B.s ? A.s < B.s : A.c != B.c ? A.c < B.c : A.m < B.m;
    }
    friend inline bool operator == (Data A, Data B) {
        return A.s == B.s && A.c == B.c && A.m == B.m;
    }
}dat[N];

int tr[K];
int lev[N], cnt[N];

namespace Input {
    const int S = 2000000;
    char s[S], *h = s+S, *t = h;
    inline char getchr(void) { if (h == t) fread(s, 1, S, stdin), h = s; return *h++; }
    inline int rd(void) {
        int f = 1; char c = getchr(); for (; !isdigit(c); c = getchr()) if (c == -) f = -1;
        int x = 0; for (; isdigit(c); c = getchr()) x = x*10+c-0; return x*f;
    }
}
using Input::rd;

inline int lowbit(int i) { return i & -i; }
inline void Add(int x, int w) { for (int i = x; i <= k; i += lowbit(i)) tr[i] += w; }
inline int Sum(int x) { int s = 0; for (int i = x; i > 0; i -= lowbit(i)) s += tr[i]; return s; }

void Solve(int L, int R) {
    if (L == R) return;
    
    int M = (L+R)>>1;
    Solve(L, M);
    Solve(M+1, R);
    
    for (int cL = L-1, cR = M+1; cR <= R; cR++) {
        while (cL+1 <= M && dat[cR].c >= dat[cL+1].c)
            Add(dat[++cL].m, 1);
        lev[dat[cR].id] += Sum(dat[cR].m);
    }
    F(cL, L, M)
        if (dat[R].c >= dat[cL].c)
            Add(dat[cL].m, -1);
        else break;
    
    static Data tmp[N];
    for (int tot = L, cL = L, cR = M+1; tot <= R; tot++)
        if (cR > R || (cL <= M && dat[cL].c <= dat[cR].c))
            tmp[tot] = dat[cL++];
        else tmp[tot] = dat[cR++];
    F(i, L, R) dat[i] = tmp[i];
}

int main(void) {
    #ifndef ONLINE_JUDGE
        freopen("xsy3262.in", "r", stdin);
        freopen("xsy3262.out", "w", stdout);
    #endif
    
    n = rd(), k = rd();
    F(i, 1, n) {
        int s = rd(), c = rd(), m = rd();
        dat[i] = Data(s, c, m, i);
    }
    
    sort(dat+1, dat+n+1);
    for (int l = 1, r; l <= n; l = r+1) {
        for (r = l-1; r+1 <= n && dat[r+1] == dat[l]; r++);
        for (int i = l, cnt = r-l; i <= r; i++, cnt--)
            lev[dat[i].id] += cnt;
    }
    Solve(1, n);
    F(i, 1, n) cnt[lev[i]]++;
    for (int i = 0; i < n; i++) printf("%d\n", cnt[i]);
    
    return 0;
}

 

[BZOJ 3262] 陌上花开 分治

标签:==   algo   ring   实现   ons   ati   二维   algorithm   bzoj   

原文地址:http://www.cnblogs.com/Sdchr/p/7251812.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!