# 【BZOJ】3262: 陌上花开

## 3262: 陌上花开

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 4031  Solved: 1902
[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

## Source

[Submit][Status][Discuss]

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int n, k, num[200005];

struct node {
int a, b, c, w, ans;
} qwq[100005], qaq[100005];

bool cmp1 ( node a, node b ) {
if ( a.a == b.a ) {
if ( a.b == b.b ) return a.c < b.c;
return a.b < b.b;
}
return a.a < b.a;
}

bool cmp2 ( node a, node b ) {
if ( a.b == b.b ) return a.c < b.c;
return a.b < b.b;
}

int lowbit ( int x ) {
return x & -x;
}

int pre[200005];

void add ( int x, int d ) {
for ( int i = x; i <= k; i += lowbit ( i ) )
pre[i] += d;
}

int query ( int x ) {
int ans = 0;
for ( int i = x; i; i -= lowbit ( i ) )
ans += pre[i];
return ans;
}

void CDQ ( int l, int r ) {
if ( l == r ) return ;
int mid = ( l + r ) >> 1;
CDQ ( l, mid ); CDQ ( mid + 1, r );
int i = mid + 1, j = l;
sort ( qaq + l, qaq + mid + 1, cmp2 );
sort ( qaq + mid + 1, qaq + r + 1, cmp2 );
for ( ; i <= r; i ++ ) {
while ( qaq[j].b <= qaq[i].b && j <= mid ) {
add ( qaq[j].c, qaq[j].w ); j ++;
}
qaq[i].ans += query ( qaq[i].c );
}
for ( i = l; i < j; i ++ ) add ( qaq[i].c, -qaq[i].w );
}

int main ( ) {
//freopen ( "testdata.in", "r", stdin );
//freopen ( "a.out", "w", stdout );
scanf ( "%d%d", &n, &k );
for ( int i = 1; i <= n; i ++ )
scanf ( "%d%d%d", &qwq[i].a, &qwq[i].b, &qwq[i].c );
sort ( qwq + 1, qwq + 1 + n, cmp1 );
int cnt = 0, sum = 0;
for ( int i = 1; i <= n; i ++ ) {
cnt ++;
if ( qwq[i].a != qwq[i+1].a || qwq[i].b != qwq[i+1].b || qwq[i].c != qwq[i+1].c ) {
qaq[++sum] = qwq[i];
qaq[sum].w = cnt;
cnt = 0;
}
}
CDQ ( 1, sum );
for ( int i = 1; i <= sum; i ++ ) num[qaq[i].ans + qaq[i].w - 1] += qaq[i].w;
for ( int i = 0; i < n; i ++ ) printf ( "%d\n", num[i] );
return 0;
}

【8.21更新】CDQ里面用sort很慢啊qwq，直接开个辅助数组归并比较优秀。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int n, k, tot;
int ans[100005];

struct node {
int a, b, c, sum, ans;
} init[100005], flower[100005];

bool cmp ( node a, node b ) {
if ( a.a == b.a ) {
if ( a.b == b.b ) return a.c < b.c;
return a.b < b.b;
}
return a.a < b.a;
}

int lowbit ( int x ) {
return x & -x;
}

int pre[200005];
void add ( int pos, int d ) {
for ( int i = pos; i <= k; i += lowbit ( i ) )
pre[i] += d;
}

int query ( int pos ) {
int ans = 0;
for ( int i = pos; i; i -= lowbit ( i ) )
ans += pre[i];
return ans;
}

node fz[100005];
void CDQ ( int L, int R ) {
if ( L == R ) return ;
int mid = ( L + R ) >> 1; int qwq = 0;
CDQ ( L, mid ); CDQ ( mid + 1, R );
int i = L, j = mid + 1;
while ( i <= mid && j <= R ) {
if ( flower[i].b <= flower[j].b ) {
fz[++qwq] = flower[i++];
} else {
flower[j].ans += query ( flower[j].c );
fz[++qwq] = flower[j++];
}
}
for ( ; j <= R; j ++ ) { flower[j].ans += query ( flower[j].c ); fz[++qwq] = flower[j]; }
for ( ; i <= mid; i ++ ) { fz[++qwq] = flower[i]; add ( flower[i].c, flower[i].sum ); }
for ( int i = L; i <= mid; i ++ ) add ( flower[i].c, -flower[i].sum );
int o = 0;
for ( i = L; i <= R; i ++ ) flower[i] = fz[++o];
}

int main ( ) {
scanf ( "%d%d", &tot, &k );
for ( int i = 1; i <= tot; i ++ )
scanf ( "%d%d%d", &init[i].a, &init[i].b, &init[i].c );
int cnt = 0;
sort ( init + 1, init + 1 + tot, cmp );
for ( int i = 1; i <= tot; i ++ ) {
cnt ++;
if ( init[i].a != init[i+1].a || init[i].b != init[i+1].b || init[i].c != init[i+1].c ) {
flower[++n] = init[i];
flower[n].sum = cnt;
cnt = 0;
}
}
CDQ ( 1, n );
for ( int i = 1; i <= n; i ++ ) ans[flower[i].ans+flower[i].sum-1] += flower[i].sum;
for ( int i = 0; i < tot; i ++ ) printf ( "%d\n", ans[i] );
return 0;
}

posted @ 2018-08-16 21:05  Wans_ovo  阅读(148)  评论(0编辑  收藏  举报