#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
template<typename T>void read(T &x){
x=0;int f(1);char c(getchar());
for(;!isdigit(c);c=getchar())if(c=='-')f=-f;
for(; isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c-'0');
x*=f;
}
struct node{
int a,b,c,id;
};
#define mid ((l+r)>>1)
#define ls node<<1
#define rs node<<1|1
#define endl '\n'
typedef pair<pair<int,int>,int> piii;
typedef long long ll;
map<piii,int>ma;
node a[N];
bool cmp(node x1,node x2){
if(x1.a!=x2.a) return x1.a<x2.a;
if(x1.b!=x2.b) return x1.b<x2.b;
return x1.c<x2.c;
}
const int V=2e5+10;
int n,k;
namespace treap{// 无旋treap (fhq-treap)
const int N = 200007, INF = 0x3f3f3f3f;
const int LOG=30;
struct fhq_treap{
int l, r;
int size;
int fa;
int val, fix;
ll sum;
}tr[N*LOG];
int cnt;
int x, y, z, root[N<<2];
inline void pushup(int p)
{
tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + 1;
tr[p].sum = tr[tr[p].l].sum + tr[tr[p].r].sum + tr[p].val;
tr[tr[p].l].fa = tr[tr[p].r].fa = p;
}
inline void split(int p, int k, int &x, int &y)//split_by_val
{
if(!p){x = y = 0; return ;}
if(tr[p].val <= k)x = p, split(tr[p].r, k, tr[p].r, y);
else y = p, split(tr[p].l, k, x, tr[p].l);
pushup(p);
}
inline int merge(int x, int y)
{
if(!x || !y)return x + y;
if(tr[x].fix > tr[y].fix){//小根堆
tr[x].r = merge(tr[x].r, y);pushup(x);return x;
}
else {
tr[y].l = merge(x, tr[y].l);pushup(y);return y;
}
}
//!得到新节点
inline int get_node(int val)
{
tr[++ cnt].size = 1;
tr[cnt].fix = rand();
tr[cnt].sum = tr[cnt].val = val;
tr[cnt].fa = 0;
return cnt;
}
//!树中插入新节点
inline void my_insert(int k,int val)
{
split(root[k], val, x, y);
root[k] = merge(merge(x, get_node(val)), y);
}
//!按值删除所有权值为k的所有点
inline void my_delet_all(int k,int val)
{
split(root[k], val, x, z);
split(x, val - 1, x, y);
root[k] = merge(x, z);
return ;
}
//!按值删除给定权值的一个点
inline void my_delet_one(int k,int val)
{
split(root[k], val, x, z);
split(x, val - 1, x, y);
y = merge(tr[y].l, tr[y].r);
root[k] = merge(merge(x, y), z);
return ;
}
//!查询指定排名的一个数,返回那个数的编号
inline int get_num_by_rank(int p, int k)
{
while(true){
if(k <= tr[tr[p].l].size)p = tr[p].l;
else if(k == tr[tr[p].l].size + 1)return p;
else k -= tr[tr[p].l].size + 1, p = tr[p].r;
}
}
//!按权值分裂时查询一个数的排名///
//!根据权值查询一个数的排名
inline int get_rank_by_val(int k,int val)
{
split(root[k], val - 1, x, y);
int res = tr[x].size + 1;
root[k] = merge(x, y);
return res;
}
//!按排名分裂时查询一个数的排名/
//!需要维护父节点
//!根据编号查询这个数的排名
inline int get_rank_by_num(int k,int p)
{
int res = tr[tr[p].l].size + 1;
while(p != root[k]){//一直回溯
if(p == tr[tr[p].fa].r)res += tr[tr[tr[p].fa].l].size + 1;
p = tr[p].fa;
}
return res;
}
inline int get_val_by_rank(int k,int rank)
{
int res = tr[get_num_by_rank(root[k], rank)].val;
return res;
}
//!查找前驱的编号
//!按值查找比它小的数中的最大的数的编号
inline int get_prev_of_num(int k,int val)
{
split(root[k], val - 1, x, y);
int res = tr[get_num_by_rank(x, tr[x].size)].val;
root[k] = merge(x, y);
return res;
}
//!查找后继的编号
//!按值查找比它大的数中最小数的编号
inline int get_next_of_num(int k,int val)
{
split(root[k], val, x, y);
int res = tr[get_num_by_rank(y, 1)].val;
root[k] = merge(x, y);
return res;
}
//!查找节点的祖先节点
inline int get_anc(int x)
{
while(tr[x].fa){
x = tr[x].fa;
}
return x;
}
inline void main()
{
srand((unsigned)time(NULL));
memset(tr, 0, sizeof tr);
cnt = 0;
}
}
void insert(int node,int l,int r,int x,int v){
treap::my_insert(node,v);
if(l==r) return;
if(x<=mid) insert(ls,l,mid,x,v);
else insert(rs,mid+1,r,x,v);
}
int query(int node,int l,int r,int ql,int qr,int val){//<=val
// cout<<node<<" "<<l<<" "<<r<<endl;
if(ql<=l&&r<=qr){
return treap::get_rank_by_val(node,val+1)-1;
return 0;
}
int ans=0;
if(ql<=mid) ans+=query(ls,l,mid,ql,qr,val);
if(qr>mid ) ans+=query(rs,mid+1,r,ql,qr,val);
return ans;
}
int ans1[N];
int ans2[N];
int main(){
srand(time(0));
read(n),read(k);
for(int i=1;i<=n;i++) {
read(a[i].a),read(a[i].b),read(a[i].c);a[i].id=i;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
int tmp=query(1,0,V,0,a[i].b,a[i].c);
ma[{{a[i].a,a[i].b},a[i].c}]++;
ans1[i]=tmp;
insert(1,0,V,a[i].b,a[i].c);
}
for(int i=1;i<=n;i++){
ans1[i]+=ma[{{a[i].a,a[i].b},a[i].c}]-1;
ma[{{a[i].a,a[i].b},a[i].c}]-=1;
ans2[ans1[i]]++;
}
for(int i=0;i<n;i++){
cout<<ans2[i]<<endl;
}
}
代码如上,t了4个点