【CJOJ2433】陌上花开 树状数组套替罪羊树

【CJOJ2433】陌上花开 树状数组套替罪羊树


蛤?bzoj?没权限QAQ
蛤?CDQ?看了好久没看懂QwQ
好吧我会拿cdq再写一遍的
为啥我感觉这东西比cdq好写
只好拿树状数组套替罪羊树水水了。
先排序一遍,保证对于所有的花,比这朵花美丽的都在它后面。(重复不算)
然后按照b建树状数组,树状数组每个节点按照c建替罪羊树。(只有插入)
然后就水过去了,,,
数组开小身败名裂QwQ因为数组开小调了一个多小时
SGT空间理论上(O(nlgn)),实际上max_=1e6也能过。

// It is made by XZZ
#include<cstdio>
#include<algorithm>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
    rg int x=0;rg bool flg=0;rg char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return flg?-x:x;
}
const int maxn=100002,maxk=200001;
typedef const int& fast;
namespace sgt{
	const double alpha=0.7233333;
	const int max_=1e6+2333;
	int cnt,gg[maxk],sum[max_],cov[max_],ch[max_][2],siz[max_],val[max_],root[maxk],id=0;
	il vd dfs(fast x){if(x)dfs(ch[x][0]),gg[++cnt]=x,dfs(ch[x][1]);}
	il int divide(int l,int r){
		if(l>r)return 0;
#define mid ((l+r)>>1)
		ch[gg[mid]][0]=divide(l,mid-1);
		ch[gg[mid]][1]=divide(mid+1,r);
		siz[gg[mid]]=r-l+1;
		cov[gg[mid]]=cov[ch[gg[mid]][0]]+cov[ch[gg[mid]][1]]+sum[gg[mid]];
		return gg[mid];
#undef mid
	}
	il int*_ins(int&x,fast num,fast total){
		if(!x){x=++id,val[x]=num,siz[x]=1,sum[x]=total,cov[x]=total;return NULL;}
		if(val[x]==num){cov[x]+=total,sum[x]+=total;return NULL;}
		int*p=_ins(ch[x][num>val[x]],num,total);
		if(siz[x]*alpha+3<min(siz[ch[x][0]],siz[ch[x][1]]))p=&x;
		siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
		cov[x]=cov[ch[x][0]]+cov[ch[x][1]]+sum[x];
		return p;
	}
	il vd ins(int rt,int num,int total){
		int*p=_ins(root[rt],num,total);
		if(p)cnt=0,dfs(root[rt]),root[rt]=divide(1,cnt);
	}
	il int query(int rt,int num){
		int ret=0,x=root[rt];
		while(x){
			if(val[x]==num)return ret+cov[ch[x][0]]+sum[x];
			if(val[x]>num)x=ch[x][0];
			else ret+=cov[ch[x][0]]+sum[x],x=ch[x][1];
		}
		return ret;
	}
}
struct frog{int a,b,c;}f[maxn];
bool operator == (const frog&a,const frog&b){return a.a==b.a&&a.b==b.b&&a.c==b.c;}
il bool cmp(const frog&a,const frog&b){
	if(a.a^b.a)return a.a<b.a;
	if(a.b^b.b)return a.b<b.b;
	return a.c<b.c;
}
int ans[maxn];
#define lb(o) ((o)&-(o))
int main(){
	int n=gi(),k=gi();
	using namespace sgt;
	rep(i,1,n)f[i].a=gi(),f[i].b=gi(),f[i].c=gi();
	sort(f+1,f+n+1,cmp);
	int __ans,cnt=0;
	rep(i,1,n){
		++cnt;
		if(f[i]==f[i+1])continue;
		__ans=0;
		for(int j=f[i].b;j;j-=lb(j))__ans+=query(j,f[i].c);
		ans[__ans+cnt-1]+=cnt;
		for(int j=f[i].b;j<=k;j+=lb(j))ins(j,f[i].c,cnt);
		cnt=0;
	}
	rep(i,1,n)printf("%d
",ans[i-1]);
	return 0;
}
原文地址:https://www.cnblogs.com/xzz_233/p/cjoj2433.html