HDU 1255

    技术2022-05-19  23

    题目大意:求矩形相交部分面积和

    #include<iostream> #include<algorithm> using namespace std; #define N 2001 struct node {     int l,r,cover;     double one_len,more_len;     int getmid(){         return (l+r)>>1;     } }p[3*N]; struct Line {     double l,r,h;     int flag; }L[N]; int m; double X[N]; double h[N]; bool cmp(Line x,Line y) {     return x.h<y.h; } int find(double x) {     int f=0,l=m-1;     while(f<=l)     {         int mid=(f+l)>>1;         if(h[mid]==x)             return mid;         if(h[mid]>x)             l=mid-1;         else             f=mid+1;     } } void setlen(int id) {     int l=p[id].l,r=p[id].r;     if(p[id].cover>1)         p[id].one_len=p[id].more_len=h[r]-h[l];     else if(p[id].cover==1)     {         p[id].one_len=h[r]-h[l];         if(p[id].l+1==p[id].r)             p[id].more_len=0;         else             p[id].more_len=p[id<<1].one_len+p[id<<1|1].one_len;     }     else     {         if(p[id].l+1==p[id].r)             p[id].more_len=p[id].one_len=0;         else         {             p[id].more_len=p[id<<1].more_len+p[id<<1|1].more_len;             p[id].one_len=p[id<<1].one_len+p[id<<1|1].one_len;         }     } } void build(int l,int r,int id) {     p[id].l=l;     p[id].r=r;     p[id].cover=0;     p[id].one_len=p[id].more_len=0;     if(r-l==1)         return;     int mid=p[id].getmid();     build(l,mid,id<<1);     build(mid,r,id<<1|1); } void update(int l,int r,int flag,int id) {     if(p[id].l==l&&r==p[id].r)     {         p[id].cover+=flag;         setlen(id);         return;     }     int mid=p[id].getmid();     if(r<=mid)         update(l,r,flag,id<<1);     else if(l>=mid)         update(l,r,flag,id<<1|1);     else     {         update(l,mid,flag,id<<1);         update(mid,r,flag,id<<1|1);     }     setlen(id); } int main(void) {     int t;     scanf("%d",&t);     while(t--)     {         int n;         scanf("%d",&n);         m=0;         while(n--)         {             double x1,y1,x2,y2;             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);             X[m]=x1;             L[m].l=x1;             L[m].r=x2;             L[m].h=y1;             L[m].flag=1;             m++;             X[m]=x2;             L[m].l=x1;             L[m].r=x2;             L[m].h=y2;             L[m].flag=-1;             m++;         }         sort(X,X+m);         sort(L,L+m,cmp);         build(0,m-1,1);         int mm=m;         m=1;         h[0]=X[0];         for(int i=1;i<mm;i++)             if(X[i]!=X[i-1])                 h[m++]=X[i];         double ans=0;         for(int i=0;i<mm-1;i++)         {             int l=find(L[i].l);             int r=find(L[i].r);             update(l,r,L[i].flag,1);             ans+=p[1].more_len*(L[i+1].h-L[i].h);         }         printf("%.2lf/n",ans);     } } 

    此时线段区间的变量不能是单纯一个len了,如果只用一个变量len的话,每次update的时候就要更新到底,这样浪费很多时间,可以设置两个变量:one_len, more_len。分别记录此区间覆盖次数>=1与>=2的长度,最后用的结果就是more_len,函数setlen()描述了如何更新这两个变量


    最新回复(0)