• 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
    ",i);
    		s1.insert(r1[i],x[i]); s2.insert(r2[i],y[i]);
    	}
    	puts("-1");
    }

  • 相关阅读:
    CodeIgniter 2.X 于 PHP5.6 兼容错误
    解决 TextMate 2 无法安装 Emmet 插件
    Windows 10 KMS 激活方法
    Sublime Text 3 如何修改默认快捷键
    Grunt快速使用笔记
    CSS3字体发光效果
    CSS3使用盒模型实现三栏布局
    CSS3Transition添加多个过渡效果
    Javascript 判断网页横竖屏
    【iOS知识汇】OC点语法的坑
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477293.html
Copyright © 2020-2023  润新知