bzoj3262: 陌上花开

题目链接

bzoj3262: 陌上花开

题解

三维偏序
第一维sort,第二cdq分治,第三bit

代码

#include<cstdio> 
#include<cstring> 
#include<algorithm> 
inline int read() {
    int x = 0,f = 1;
    char c = getchar(); 
    while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} 
    while(c <= '9' && c >= '0')x = x * 10 + c -'0',c = getchar(); 
    return x * f;  
} 
const int maxw = 200007; 
const int maxn = 100007; 
int n,k; 
 
struct Query {
    int a,b,c,w,ans; 
    bool operator<(const Query &B)const {
        return a < B.a || (a == B.a && b < B.b) || (a == B.a && b == B.b && c < B.c);
    } 
} query[maxn],tmp[maxn],t[maxn]; 
int ans[maxn];  
namespace BIT {
#define lowbit(x) (x & -x) 
    int sum[maxw << 1]; 
    void add(int idx,int val) { 
        for(;idx <= k;idx += lowbit(idx)) sum[idx] += val;  
    } 
    int query(int idx) { 
        int ret = 0; 
        for(;idx;idx -= lowbit(idx)) ret += sum[idx]; 
        return ret; 
    } 
    void clear(int idx) { 
        for(;idx <= k;idx += lowbit(idx)) { 
            if(sum[idx]) sum[idx] = 0; 
            else break; 
        } 
    } 
} 
  
void cdq(int l,int r) {
    if(r - l <= 1) return;
    int mid = l + r >> 1;cdq(l,mid);cdq(mid,r); 
    int p = l,q = mid,cnt = l; 
    for(;p < mid && q < r;) { 
        if(query[p].b <= query[q].b) { 
            BIT::add(query[p].c,query[p].w); 
            tmp[cnt ++] = query[p ++]; 
        } 
        else { 
            query[q].ans += BIT::query(query[q].c); 
            tmp[cnt ++] = query[q ++]; 
        } 
    } 
    while(p < mid)tmp[cnt ++] = query[p ++]; 
    while(q < r) {
        query[q].ans += BIT::query(query[q].c); 
        tmp[cnt ++] = query[q ++]; 
    } 
    for(int i = l;i < r;++ i)  {
        BIT::clear(query[i].c); 
        query[i] = tmp[i];      
    } 
} 
int qid; 
int main() { 
    n = read(); k = read(); 
    for(int i = 1;i <= n;++ i) 
        t[i].a = read(), t[i].b = read(),  t[i].c = read(),t[i].w = 1; 
    std::sort(t + 1,t + n + 1); 
    for(int i = 1;i <= n;++ i) {     
        if(i == 1 || !(t[i].b == t[i - 1].b && t[i].a == t[i - 1].a && t[i].c == t[i - 1].c)) query[qid ++] = t[i]; 
        else query[qid - 1].w ++; 
    } 
    cdq(0,qid); 
    for(int i = 0;i < qid;++ i) ans[query[i].ans + query[i].w - 1] += query[i].w; 
    for(int i = 0;i < n;++ i)  
        printf("%d\n",ans[i]); 
    return 0; 
} 
posted @ 2018-07-02 21:37  zzzzx  阅读(106)  评论(0编辑  收藏  举报