# [BZOJ3262]陌上花开

## 3262: 陌上花开

Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 2497  Solved: 1115 [Submit][Status][Discuss]

10 3
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1

3
1
3
0
1
0
1
0
0
1

## HINT

1 <= N <= 100,000, 1 <= K <= 200,000

CDQ分治

#include <cstdio>
#include <algorithm>
using namespace std;
char buf[10000000], *ptr = buf - 1;
int n = 0;
char ch = *++ptr;
while(ch < '0' || ch > '9') ch = *++ptr;
while(ch <= '9' && ch >= '0'){
n = (n << 1) + (n << 3) + ch - '0';
ch = *++ptr;
}
return n;
}
const int maxn = 100000 + 10, maxk = 200000 + 10;
int n, k;
int arr[maxk] = {0};
inline void Update(int w, int s){
for(; w <= k; w += w & -w) arr[w] += s;
}
inline int Query(int w){
int s = 0;
for(; w; w -= w & -w) s += arr[w];
return s;
}
struct Node{
int a, b, c, id, s;
Node(){}
Node(int _a, int _b, int _c, int _id = 0, int _s = 1): a(_a), b(_b), c(_c), id(_id), s(_s){}
}tp[maxn], no[maxn];
class cmp{
public:
bool operator () (const Node &x, const Node &y){
return x.a == y.a ? x.b == y.b ? x.c < y.c : x.b < y.b : x.a < y.a;
}
};
int rank[maxn] = {0}, cnt[maxn] = {0};
void CDQ(int l, int r){
if(l == r) return;
int mid = l + r >> 1, ll = l, rr = mid + 1, tcnt = 0;
CDQ(l, mid); CDQ(mid + 1, r);
while(ll <= mid && rr <= r){
if(no[ll].b <= no[rr].b){
Update(no[ll].c, no[ll].s);
tp[++tcnt] = no[ll++];
}
else{
rank[no[rr].id] += Query(no[rr].c);
tp[++tcnt] = no[rr++];
}
}
while(ll <= mid){
Update(no[ll].c, no[ll].s);
tp[++tcnt] = no[ll++];
}
while(rr <= r){
rank[no[rr].id] += Query(no[rr].c);
tp[++tcnt] = no[rr++];
}
for(int i = l; i <= mid; i++) Update(no[i].c, -no[i].s);
for(int i = 1; i <= tcnt; i++) no[l + i - 1] = tp[i];
}
int main(){
fread(buf, sizeof(char), sizeof(buf), stdin);
int N = readint(); n = 0;
tp[0] = Node(0, 0, 0, 0, 0);
for(int a, b, c, i = 1; i <= N; i++){
tp[i] = Node(a, b, c);
}
sort(tp + 1, tp + N + 1, cmp());
for(int i = 1; i <= N; i++){
if(tp[i].a == no[n].a && tp[i].b == no[n].b && tp[i].c == no[n].c) no[n].s++;
else no[++n] = Node(tp[i].a, tp[i].b, tp[i].c, n);
}
CDQ(1, n);
for(int i = 1; i <= n; i++) cnt[rank[no[i].id] + no[i].s - 1] += no[i].s;
for(int i = 0; i < N; i++) printf("%d\n", cnt[i]);
return 0;
}

posted @ 2017-09-23 11:19  Elder_Giang  阅读(115)  评论(0编辑  收藏  举报