Jzoj4737 金色丝线将瞬间一分为二(GOSICK系列)

继续上一篇那套题


可以将x,y宙分开讨论,对于每一维维护一个数据结构求出所有比之小的部分的和和比之大的部分的和

所以我们先将这些点分别按x,y轴排序,得到rankx和ranky之后用树状数组即可

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL long long
#define N 600010
#define mid (l+r>>1)
using namespace std;
int x[N],y[N],r1[N],r2[N],n,v[N]; LL b,c,S=0,d; 
struct Seg{
	LL s[N]; int c[N];
	void insert(int x,int k){ for(;x<=n;x+=x&-x) s[x]+=k,++c[x]; }
	LL sum(int x,LL& C,LL S=0){ for(;x;x^=x&-x) S+=s[x],C+=c[x]; return S; }
	LL query(int l,int r,LL& cnt){
		LL c1,S=sum(r,cnt)-sum(l-1,c1); cnt-=c1; return S;
	}
} s1,s2;
inline bool c1(int a,int b){ return x[a]<x[b]; }
inline bool c2(int a,int b){ return y[a]<y[b]; }
int main(){ 
	scanf("%d%lld",&n,&d);
	for(int i=1;i<=n;++i){
		r1[i]=r2[i]=i;
		scanf("%d%d",x+i,y+i);
	}
	sort(r1+1,r1+1+n,c1);
	sort(r2+1,r2+1+n,c2);
	for(int i=1;i<=n;++i) v[r1[i]]=i; memcpy(r1,v,sizeof v);
	for(int i=1;i<=n;++i) v[r2[i]]=i; memcpy(r2,v,sizeof v);
	for(int i=1;i<=n;++i){
		c=0; b=s1.query(1,r1[i],c); S+=c*x[i]-b;
		c=0; b=s1.query(r1[i],n,c); S+=b-c*x[i];
		c=0; b=s2.query(1,r2[i],c); S+=c*y[i]-b;
		c=0; b=s2.query(r2[i],n,c); S+=b-c*y[i];
		if(S>d) return 0&printf("%d\n",i);
		s1.insert(r1[i],x[i]); s2.insert(r2[i],y[i]);
	}
	puts("-1");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值