BZOJ3839: [Pa2013]Działka

来源:互联网 发布:建筑设计优化的方法 编辑:程序博客网 时间:2024/05/01 10:32

卡时限过去
(多刷几次就好啦

凸壳分成四块 扫描线加线段树处理边界点
根据预处理的边界点之间凸壳面积计算

面积计算以原点为三角形的第三个节点 注意每一块面积对答案的贡献是正的还是负的
这题居然花了我一天时间

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;#define abs(a) ((a)<0?-(a):(a))#define ll long longll A[3001][3001],B[3001][3001],C[3001][3001],D[3001][3001];struct Flag{    int a,b;    Flag(){};    Flag(int a,int b):a(a),b(b){}    inline friend Flag operator +(Flag a,Flag b){return a.b>b.b?a:b;}    inline friend bool operator !=(Flag a,Flag b){return a.b^b.b;}};Flag NUL=Flag(-1,-1);struct Node{    Flag A,f;    int l,r;    Node *lc,*rc;    Node():f(NUL),A(NUL),lc(NULL),rc(NULL){};    Node(int x,int y):l(x),r(y),A(NUL),lc(NULL),rc(NULL),f(NUL){};}Q7[1000001];int Cnt;inline Node *Build(int l,int r){Q7[++Cnt]=Node(l,r);return Q7+Cnt;}inline void pushdown(Node *Cur){    if(Cur->lc==NULL)Cur->lc=Build(Cur->l,Cur->l+Cur->r>>1),Cur->rc=Build((Cur->l+Cur->r>>1)+1,Cur->r);    Cur->lc->A=Cur->rc->A=Cur->lc->f=Cur->rc->f=Cur->f;    Cur->f=NUL;}inline void Update(Node *Cur,int l,Flag Delt){    if(!Cur)return;    if(Cur->l>=l&&l>=Cur->r){Cur->A=Cur->f=Delt;return;}    if(Cur->f!=NUL)pushdown(Cur);    Cur->A=Delt;    int mid=Cur->l+Cur->r>>1;    if(!Cur->lc)        Cur->lc=Build(Cur->l,mid),Cur->rc=Build(mid+1,Cur->r);    if(l<=mid)Update(Cur->lc,l,Delt);    else Update(Cur->rc,l,Delt);}Flag Query(Node *Cur,int l,int r){    if(!Cur)return NUL;    int mid=Cur->l+Cur->r>>1;    if(l<=Cur->l&&r>=Cur->r)return Cur->A;    Flag res=NUL;    if(l<=mid)res=res+Query(Cur->lc,l,r);    if(r>mid)res=res+Query(Cur->rc,l,r);    return res+Cur->f;}struct P{    int x,y,i;    P(){}    P(int x,int y):x(x),y(y){}    inline friend ll operator *(P a,P b){return a.x*1ll*b.y-a.y*1ll*b.x;}    inline friend P operator -(P a,P b){return P(a.x-b.x,a.y-b.y);}}L[3001];inline bool cmp1(P a,P b){return a.x^b.x?a.x<b.x:a.y<b.y;}inline bool cmp2(P a,P b){return a.x^b.x?a.x<b.x:a.y>b.y;}inline bool cmp3(P a,P b){return a.x^b.x?a.x>b.x:a.y<b.y;}inline bool cmp4(P a,P b){return a.x^b.x?a.x>b.x:a.y>b.y;}inline bool cmp5(P a,P b){return a.x^b.x?a.x<b.x:a.y<b.y;}inline bool cmp6(P a,P b){return a.y^b.y?a.y<b.y:a.x<b.x;}inline bool cmp7(P a,P b){return a.x^b.x?a.x>b.x:a.y>b.y;}inline bool cmp8(P a,P b){return a.y^b.y?a.y>b.y:a.x>b.x;}struct Q{    int P;    int no;}sx[1000001],ex[1000001],sy[1000001],ey[1000001];int EX[1000001],EY[1000001],SX[1000001],SY[1000001];int  Ex[1000001],Ey[1000001],Sx[1000001],Sy[1000001];bool Ans[1000001];inline bool cmps(Q a,Q b){return a.P<b.P;}inline bool cmpe(Q a,Q b){return a.P>b.P;}P Bl=P(-0,-0);char c;bool flag;inline void read(int &a){a=0;do c=getchar(); while(c!='-'&&(c<'0'||c>'9'));c=c=='-'?flag=true,getchar():c;while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();a=flag?flag=false,-a:a;}int stack[100001],top;int main(){    int n,k;    read(k),read(n);    for(int i=1;i<=n;i++)read(L[i].x),read(L[i].y),L[i].i=i;    sort(L+1,L+1+n,cmp1);    for(int i=1;i<n;i++)        {            stack[top=1]=i;            for(int j=i+1;j<=n;j++)if(L[j].y>=L[i].y)            {                while(top>1&&(L[stack[top]]-L[stack[top-1]])*(L[j]-L[stack[top-1]])<=0)top--;                stack[++top]=j;                A[L[i].i][L[j].i]=L[stack[top-1]]*L[stack[top]]+A[L[i].i][L[stack[top-1]].i];            }        }    sort(L+1,L+1+n,cmp2);    for(int i=1;i<n;i++)        {            stack[top=1]=i;            for(int j=i+1;j<=n;j++)if(L[j].y<=L[i].y)            {                while(top>1&&(L[stack[top]]-L[stack[top-1]])*(L[j]-L[stack[top-1]])>=0)top--;                stack[++top]=j;                B[L[i].i][L[j].i]=L[stack[top-1]]*L[stack[top]]+B[L[i].i][L[stack[top-1]].i];            }        }    sort(L+1,L+1+n,cmp3);    for(int i=1;i<n;i++)        {            stack[top=1]=i;             for(int j=i+1;j<=n;j++)if(L[j].y>=L[i].y)            {                while(top>1&&(L[stack[top]]-L[stack[top-1]])*(L[j]-L[stack[top-1]])>=0)top--;                stack[++top]=j;                C[L[i].i][L[j].i]=L[stack[top-1]]*L[stack[top]]+C[L[i].i][L[stack[top-1]].i];            }        }    sort(L+1,L+1+n,cmp4);    for(int i=1;i<n;i++)        {            stack[top=1]=i;            for(int j=i+1;j<=n;j++)if(L[j].y<=L[i].y)            {                while(top>1&&(L[stack[top]]-L[stack[top-1]])*(L[j]-L[stack[top-1]])<=0)top--;                stack[++top]=j;                D[L[i].i][L[j].i]=L[stack[top-1]]*L[stack[top]]+D[L[i].i][L[stack[top-1]].i];            }        }    int m;    read(m);    for(int i=1;i<=m;i++)        read(sx[i].P),read(ex[i].P),read(sy[i].P),read(ey[i].P),        sx[i].no=sy[i].no=ex[i].no=ey[i].no=i,        Sx[i]=sx[i].P,Sy[i]=sy[i].P,Ex[i]=ex[i].P,Ey[i]=ey[i].P;    sort(L+1,L+1+n,cmp6);    sort(ey+1,ey+1+m,cmps);    int j=1;    Cnt=0;    Node *MYT=Build(0,k);    for(int i=1;i<=m;i++)    {        while(j<=n&&L[j].y<=ey[i].P)Update(MYT,L[j].x,Flag(L[j].i,j)),j++;        Flag T;        EY[ey[i].no]=(T=Query(MYT,Sx[ey[i].no],Ex[ey[i].no])).a;        if(T.b==-1||Sy[ey[i].no]>L[T.b].y)Ans[ey[i].no]=true;    }Cnt=0;    MYT=Build(0,k);    sort(L+1,L+1+n,cmp8);    sort(sy+1,sy+1+m,cmpe);    j=1;    for(int i=1;i<=m;i++)    {        while(j<=n&&L[j].y>=sy[i].P)Update(MYT,L[j].x,Flag(L[j].i,j)),j++;        Flag T;        SY[sy[i].no]=(T=Query(MYT,Sx[sy[i].no],Ex[sy[i].no])).a;        if(T.b==-1||Ey[sy[i].no]<L[T.b].y)Ans[sy[i].no]=true;    }Cnt=0;    MYT=Build(0,k);    sort(L+1,L+1+n,cmp5);    sort(ex+1,ex+1+m,cmps);    j=1;    for(int i=1;i<=m;i++)    {        while(j<=n&&L[j].x<=ex[i].P)Update(MYT,L[j].y,Flag(L[j].i,j)),j++;        Flag T;        EX[ex[i].no]=(T=Query(MYT,Sy[ex[i].no],Ey[ex[i].no])).a;        if(T.b==-1||Sx[ex[i].no]>L[T.b].x)Ans[ex[i].no]=true;    }    sort(L+1,L+1+n,cmp7);    sort(sx+1,sx+1+m,cmpe);    j=1;Cnt=0;    MYT=Build(0,k);    for(int i=1;i<=m;i++)    {        while(j<=n&&L[j].x>=sx[i].P)Update(MYT,L[j].y,Flag(L[j].i,j)),j++;        Flag T;        SX[sx[i].no]=(T=Query(MYT,Sy[sx[i].no],Ey[sx[i].no])).a;        if(T.b==-1||Ex[sx[i].no]<L[T.b].x)Ans[sx[i].no]=true;    }    for(int i=1;i<=m;i++)    {        ll ans=0;        if(SY[i]==-1||EY[i]==-1||EX[i]==-1||SX[i]==-1){puts("0.0");continue;}        if(Ans[i]){puts("0.0");continue;}        ans=A[SY[i]][EX[i]]-B[EY[i]][EX[i]]-C[SY[i]][SX[i]]+D[EY[i]][SX[i]];        printf("%lld.%d\n",ans>>1,ans&1?5:0);    }    return 0;}
0 0
原创粉丝点击