非常蒟蒻的我今天学了学cdq分治.. 感觉好厉害呀..
模板题:bzoj3262
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int Maxn = 110000;
struct node {
int s, c, m, sum, num;
}list[Maxn], b1[Maxn], b2[Maxn]; int bl1, bl2;
int _min ( int x, int y ){ return x < y ? x : y; }
int n, K;
int ans[Maxn], pans[Maxn];
int c[Maxn*2];
bool cmp1 ( node x, node y ){
if ( x.s != y.s ) return x.s < y.s;
if ( x.c != y.c ) return x.c < y.c;
return x.m < y.m;
}
bool cmp2 ( node x, node y ){ return x.c < y.c; }
int lowbit ( int x ){ return x & (-x); }
void add ( int x, int k ){
while ( x <= K ){
c[x] += k;
x += lowbit (x);
}
}
int query ( int x ){
int ret = 0;
while ( x > 0 ){
ret += c[x];
x -= lowbit (x);
}
return ret;
}
void cdq ( int l, int r ){
if ( l == r ) return;
int i, j, k;
int mid = ( l + r ) >> 1;
bl1 = bl2 = 0;
for ( i = l; i <= mid; i ++ ) b1[++bl1] = list[i];
for ( i = mid+1; i <= r; i ++ ) b2[++bl2] = list[i];
sort ( b1+1, b1+bl1+1, cmp2 );
sort ( b2+1, b2+bl2+1, cmp2 );
i = 1; j = 1;
while ( i <= bl1 && j <= bl2 ){
if ( b1[i].c <= b2[j].c ){
add ( b1[i].m, b1[i].sum );
i ++;
}
else {
ans[b2[j].num] += query (b2[j].m);
j ++;
}
}
for ( k = j; k <= bl2; k ++ ) ans[b2[k].num] += query (b2[k].m);
for ( k = 1; k <= i-1; k ++ ) add ( b1[k].m, -b1[k].sum );
cdq ( l, mid );
cdq ( mid+1, r );
}
int main (){
int i, j, k;
scanf ( "%d%d", &n, &K );
int kn = n;
for ( i = 1; i <= n; i ++ ){
scanf ( "%d%d%d", &list[i].s, &list[i].c, &list[i].m );
}
sort ( list+1, list+n+1, cmp1 );
int tmp = 1; list[1].sum = 1;
for ( i = 2; i <= n; i ++ ){
if ( list[i].s != list[tmp].s || list[i].c != list[tmp].c || list[i].m != list[tmp].m ){
list[++tmp] = list[i]; list[tmp].sum = 1;
}
else list[tmp].sum ++;
}
n = tmp;
for ( i = 1; i <= n; i ++ ) list[i].num = i;
memset ( ans, 0, sizeof (ans) );
cdq ( 1, n );
memset ( pans, 0, sizeof (pans) );
for ( i = 1; i <= n; i ++ ) pans[ans[i]+list[i].sum-1] += list[i].sum;
for ( i = 0; i < kn; i ++ ) printf ( "%d\n", pans[i] );
return 0;
}