关于卡常
查看原帖
关于卡常
189394
黑客楼主2020/8/18 15:28

RT,蒟蒻TLE两个点80分,怎么卡常也过不了。

请大佬康康!

#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define lowbit(x) (x&(-x))
#define INF 0x7fffffff
#define r(x) x=read()
#define in inline
#define re register int
int read(){
	int f=1,w=0;char ch;
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){w=w*10+ch-48;ch=getchar();}
	return w*f;
}
int n,k,t[2*N],Ans[N],tot,temp=0;
struct node{
	int a,b,c,ans,cnt;
}p[N],tmp[N],s[N];
bool operator < (const node &x,const node &y){
	return x.a<y.a||(x.a==y.a&&x.b<y.b)||(x.a==y.a&&x.b==y.b&&x.c<y.c);
}
bool operator == (const node &x,const node &y){
	return x.a==y.a&&x.b==y.b&&x.c==y.c;
}
in void add(int x,int y){
	for(re i=x;i<=k;i+=lowbit(i))t[i]+=y;
}
in int query(int x){
	int sum=0;
	for(re i=x;i;i-=lowbit(i))sum+=t[i];
	return sum;
}
void CDQ(int l,int r){
	if(l==r)return;
	int mid=l+r>>1,t1=l,t2=mid+1,cnt=0;
	CDQ(l,mid);CDQ(mid+1,r);
	for(re i=0;i<=k;i++)t[i]=0;
	while(t1<=mid&&t2<=r){
		while(p[t1].b<=p[t2].b&&t1<=mid){add(p[t1].c,p[t1].cnt);tmp[++cnt]=p[t1];t1++;}
		p[t2].ans+=query(p[t2].c);
		tmp[++cnt]=p[t2];
		t2++;
	}
	while(t1<=mid)tmp[++cnt]=p[t1++];
	while(t2<=r)p[t2].ans+=query(p[t2].c),tmp[++cnt]=p[t2++];
	cnt=0;
	for(re i=l;i<=r;i++)p[i]=tmp[++cnt];
	return;
}
int main(){
	r(n);r(k);
	for(re i=1;i<=n;i++){
		r(s[i].a);r(s[i].b);r(s[i].c);
		s[i].cnt=1;
	}
	sort(s+1,s+n+1);
	for(re i=1;i<=n;i++){
		if(s[i]==s[i-1]){
			int t0=i;
			while(t0<=n&&s[t0]==s[i-1]){
				s[t0].a=-1;s[i-1].cnt++;t0++;
			}
			i=t0;
		}
	}
	for(re i=1;i<=n;i++)if(s[i].a!=-1)p[++temp]=s[i];
	tot=n;
	n=temp;
	CDQ(1,n);
	for(re i=1;i<=n;i++)p[i].ans+=p[i].cnt-1;
	for(re i=1;i<=n;i++)Ans[p[i].ans]+=p[i].cnt;
	for(re i=0;i<tot;i++)printf("%d\n",Ans[i]);
	return 0;
}
2020/8/18 15:28
加载中...