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
  • 相关阅读:
    在 Windows 上测试 Redis Cluster的集群填坑笔记
    vmware安装黑苹果教程
    微信支付v3发布到iis时的证书问题
    Linux下安装SQL Server 2016(连接篇SQL Server on linux)
    Linux下安装SQL Server 2016(连接篇SQL Server on linux)
    Linux下安装SQL Server 2016(安装篇SQL Server on linux)
    Linux下安装SQL Server 2016(准备篇SQL Server on linux)
    客服端与服务端APP支付宝支付接口联调的那些坑
    ASP.NET MVC]WebAPI应用支持HTTPS的经验总结
    .net平台下C#socket通信(中)
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10285812.html
Copyright © 2011-2022 走看看