zoukankan      html  css  js  c++  java
  • bzoj3839【Pa2013】Działka

    题目描述

    平面上有n个不重复的点。每次询问一个边平行坐标轴的矩形内(包含边界)的点组成的凸包的面积。、

    输入格式

    第一行两个整数k,n(1<=k<=1000000,3<=n<=3000)。
    接下来n行,每行两个整数x_i,y_i(0<=x_i,y_i<=k),表示点的坐标。
    接下来一行一个整数m(1<=m<=1000000),表示询问数量。
    接下来m行,每行四个整数a,b,c,d(0<=a<b<=k,0<=c<d<=k),表示询问的矩形范围为a<=x<=b,c<=y<=d。

    输出格式

    对于每个询问输出一行表示面积。保留小数点后一位。

    • 题解

      • 这里的方向处理有点略微不同;
      • 可以用排序扫描线+线段树维护出矩形边框四个方向可以卡住的切点,从南逆时针记为:$Ns,Ne,Nn,Nw$;
      • $O(n^2)A$处理出一个点沿四个象限伸展且横纵坐标均单调的凸包,并处理出从沿凸包从$A$走到$B$的叉积和;
      • 沿着$Ns,Ne,Nn,Nw$绕一圈查询对应象限的叉积和就$O(1)$求出面积;
      • 由于一三,二四象限一定不会有交集所以可以分别存在一起;
      • 注意由于要维护叉积求凸包的排序要有优先级;
      • 算了说不清楚,。。。,还是去看Claris的题解吧。。。。。。TAT
      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 #define il inline 
      4 #define ls (k<<1)
      5 #define rs (k<<1|1)
      6 using namespace std;
      7 const int N=3010,M=1000010;
      8 int n,m,q,Ne[M],Nw[M],Nn[M],Ns[M],top,T[N];
      9 int mx[M<<2];
     10 ll A[N][N],B[N][N];
     11 struct poi{
     12     int x,y,z,w;
     13     poi(int _x=0,int _y=0,int _z=0,int _w=0):x(_x),y(_y),z(_z),w(_w){};
     14     poi operator -(const poi&a){return poi(x-a.x,y-a.y);}
     15 }P[N],Q[M],que[N];
     16 struct data{int a,b,c,d;}D[M];
     17 il bool cmp1(const poi&a,const poi&b){return a.x==b.x?a.y<b.y:a.x<b.x;}
     18 il bool cmp2(const poi&a,const poi&b){return a.y==b.y?a.x>b.x:a.y<b.y;}
     19 il bool cmpx(const poi&a,const poi&b){return /*a.x==b.x?a.y<b.y:*/a.x<b.x;}
     20 il bool cmpy(const poi&a,const poi&b){return /*a.y==b.y?a.x>b.x:*/a.y<b.y;}
     21 il char gc(){
     22     static char*p1,*p2,s[1000000];
     23     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
     24     return(p1==p2)?EOF:*p1++;
     25 }
     26 il int rd(){
     27     int x=0; char c=gc();
     28     while(c<'0'||c>'9')c=gc();
     29     while(c>='0'&&c<='9'){x=x*10+c-'0';c=gc();}
     30     return x;    
     31 }
     32 ll crs(poi a,poi b){return (ll)a.x*b.y-(ll)a.y*b.x;}
     33 il int Max(int a,int b){return T[a]<T[b]?b:a;}
     34 il int query(int k,int l,int r,int x,int y){
     35     if(l==x&&r==y)return mx[k];
     36     else {
     37         int mid=(l+r)>>1;
     38         if(y<=mid)return query(ls,l,mid,x,y);
     39         else if(x>mid)return query(rs,mid+1,r,x,y);
     40         else return Max(query(ls,l,mid,x,mid),query(rs,mid+1,r,mid+1,y));
     41     }
     42 }
     43 il void update(int k,int l,int r,int x,int v){
     44     if(l==r)mx[k]=v;
     45     else{
     46         mx[k]=v;
     47         int mid=(l+r)>>1;
     48         if(x<=mid)update(ls,l,mid,x,v);
     49         else update(rs,mid+1,r,x,v);
     50     }
     51 }
     52 void build(int k,int l,int r){
     53     mx[k]=0;
     54     if(l==r){T[l]=0;return;}
     55     int mid=(l+r)>>1;
     56     build(ls,l,mid);
     57     build(rs,mid+1,r);
     58 }
     59 int main(){
     60     freopen("bzoj3839.in","r",stdin);
     61     freopen("bzoj3839.out","w",stdout);
     62     n=rd(); m=rd();
     63     for(int i=1;i<=m;++i)P[i].x=rd(),P[i].y=rd(),P[i].z=i;
     64     
     65     sort(P+1,P+m+1,cmp1);
     66     for(int i=1;i<=m;++i){
     67         que[top=1]=P[i];
     68         for(int j=i-1;j;--j)if(P[j].y<=P[i].y){
     69             while(top>1&&crs(que[top]-que[top-1],P[j]-que[top])<=0)top--;
     70             que[++top]=P[j];
     71             A[P[i].z][P[j].z]=A[P[i].z][que[top-1].z]+crs(que[top-1],P[j]);
     72         }
     73         que[top=1]=P[i];
     74         for(int j=i+1;j<=m;++j)if(P[j].y>=P[i].y){
     75             while(top>1&&crs(que[top]-que[top-1],P[j]-que[top])<=0)top--;
     76             que[++top]=P[j];
     77             A[P[i].z][P[j].z]=A[P[i].z][que[top-1].z]+crs(que[top-1],P[j]);
     78         }
     79     }
     80     sort(P+1,P+m+1,cmp2);
     81     for(int i=1;i<=m;++i){
     82         que[top=1]=P[i];
     83         for(int j=i-1;j;--j)if(P[j].x>=P[i].x){
     84             while(top>1&&crs(que[top]-que[top-1],P[j]-que[top])<=0)top--;
     85             que[++top]=P[j];
     86             B[P[i].z][P[j].z]=B[P[i].z][que[top-1].z]+crs(que[top-1],P[j]);
     87         }
     88         que[top=1]=P[i];
     89         for(int j=i+1;j<=m;++j)if(P[j].x<=P[i].x){
     90             while(top>1&&crs(que[top]-que[top-1],P[j]-que[top])<=0)top--;
     91             que[++top]=P[j];
     92             B[P[i].z][P[j].z]=B[P[i].z][que[top-1].z]+crs(que[top-1],P[j]);
     93         }
     94     }
     95     
     96     q=rd();for(int i=1;i<=q;++i)D[i].a=rd(),D[i].b=rd(),D[i].c=rd(),D[i].d=rd();
     97     
     98     sort(P+1,P+m+1,cmpx);
     99     for(int i=1;i<=q;++i)Q[i]=(poi){D[i].a,D[i].c,D[i].d,i};
    100     sort(Q+1,Q+q+1,cmpx);
    101     build(1,0,n);
    102     for(int i=q,j=m;i;--i){
    103         while(j&&P[j].x>=Q[i].x)T[P[j].z]=m-j+1,update(1,0,n,P[j].y,P[j].z),j--;
    104         Nw[Q[i].w]=query(1,0,n,Q[i].y,Q[i].z);
    105     }
    106     
    107     for(int i=1;i<=q;++i)Q[i]=(poi){D[i].b,D[i].c,D[i].d,i};
    108     sort(Q+1,Q+q+1,cmpx);
    109     build(1,0,n);
    110     for(int i=1,j=1;i<=q;++i){
    111         while(j<=m&&P[j].x<=Q[i].x)T[P[j].z]=j,update(1,0,n,P[j].y,P[j].z),j++;
    112         Ne[Q[i].w]=query(1,0,n,Q[i].y,Q[i].z);
    113     }
    114     
    115     sort(P+1,P+m+1,cmpy);
    116     for(int i=1;i<=q;++i)Q[i]=(poi){D[i].c,D[i].a,D[i].b,i};
    117     sort(Q+1,Q+q+1,cmpx);
    118     build(1,0,n);
    119     for(int i=q,j=m;i;--i){
    120         while(j&&P[j].y>=Q[i].x)T[P[j].z]=m-j+1,update(1,0,n,P[j].x,P[j].z),j--;
    121         Ns[Q[i].w]=query(1,0,n,Q[i].y,Q[i].z);
    122     }
    123     
    124     for(int i=1;i<=q;++i)Q[i]=(poi){D[i].d,D[i].a,D[i].b,i};
    125     sort(Q+1,Q+q+1,cmpx);
    126     build(1,0,n);
    127     for(int i=1,j=1;i<=q;++i){
    128         while(j<=m&&P[j].y<=Q[i].x)T[P[j].z]=j,update(1,0,n,P[j].x,P[j].z),j++;
    129         Nn[Q[i].w]=query(1,0,n,Q[i].y,Q[i].z);
    130     }
    131     for(int i=1;i<=q;++i){
    132         ll ans = A[Ns[i]][Ne[i]] + B[Ne[i]][Nn[i]] + A[Nn[i]][Nw[i]] + B[Nw[i]][Ns[i]];
    133     //    printf("%lld %lld %lld %lld
    ",A[Nn[i]][Nw[i]],B[Ne[i]][Nn[i]],B[Nw[i]][Ns[i]],A[Ns[i]][Ne[i]]);
    134     //    printf("%d %d %d %d
    ",Nn[i],Nw[i],Ns[i],Ne[i]);
    135         printf("%.1lf
    ",ans/2.0);
    136     }
    137     return 0;
    138 }
    bzoj3839
  • 相关阅读:
    (基础) --- KMP字符串
    (基础)--- 前缀和、差分
    PHOTOSHOP --- 分辨率、图片保存格式
    Oracle Delete数据后手动释放空间
    掌握爬虫技术需要学哪些内容?
    如何用python制作动态二维码,来哄女朋友开心?
    python为什么会环境变量设置不成功
    python和js交互调用的方法
    基于PHP实现解密或加密Cloudflar邮箱保护
    基于pytorch中的Sequential用法说明
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10285812.html
Copyright © 2011-2022 走看看