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;
}