zoukankan      html  css  js  c++  java
  • 【hdu1828/poj1177】线段树求矩形周长并

    题意如图

    题解:这题非常类似与矩形面积并,也是维护一个被覆盖了一次以上的线段总长。

    但是周长要算新出现的,所以每次都要和上一次做差求绝对值。

    x轴做一遍,y轴做一遍。

    但是有个问题:矩形边界重合的时候的处理。举个例子,在处理x轴的时候:

    怎么处理呢?我们在对y排序的时候把下边界(下边界+1,上边界-1)排在上边界前面,这样做就不会重复算了。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 using namespace std;
      8 
      9 typedef long long LL;
     10 const int N=10*5000,INF=(int)1e9;
     11 struct node{
     12     int x1,x2,y,d;
     13 }a[N];
     14 struct point{
     15     int x,y;LL d;
     16 }p[N];
     17 struct trnode{
     18     int l,r,lc,rc,cnt;
     19     LL rl,len;
     20 }t[2*N];
     21 int n,mx,pl,al,tl,z[N][4];
     22 LL num[N];
     23 
     24 bool cmp_d(point x,point y){return x.d<y.d;}
     25 bool cmp_y(node x,node y)
     26 {
     27     if(x.y==y.y) return x.d>y.d;//处理重边
     28     else return x.y<y.y;
     29 }
     30 void inp(int x,int y,int d){p[++pl].x=x;p[pl].y=y;p[pl].d=d;}
     31 void ina(int x1,int x2,int y,int d){a[++al].x1=x1;a[al].x2=x2;a[al].y=y;a[al].d=d;}
     32 int myabs(int x){return x>0 ? x:-x;}
     33 int maxx(int x,int y){return x>y ? x:y;}
     34 
     35 void unique()
     36 {
     37     int now=0;p[0].d=INF;
     38     sort(p+1,p+1+pl,cmp_d);
     39     for(int i=1;i<=pl;i++)
     40     {
     41         if(p[i].d!=p[i-1].d) now++,num[now]=(LL)p[i].d;
     42         z[p[i].x][p[i].y]=now;
     43     }
     44     mx=now;
     45 }
     46 
     47 void make_edge()
     48 {
     49     al=0;mx=0;
     50     for(int i=1;i<=n;i++)
     51     {
     52         if(z[i][0]>z[i][2]) swap(z[i][0],z[i][2]);
     53         if(z[i][1]>z[i][3]) swap(z[i][1],z[i][3]);
     54         ina(z[i][0],z[i][2],z[i][1],1);
     55         ina(z[i][0],z[i][2],z[i][3],-1);
     56         mx=maxx(mx,z[i][2]);
     57     }
     58     // ina(1,mx-1,INF,-1);
     59 }
     60 
     61 int bt(int l,int r)
     62 {
     63     int x=++tl;
     64     t[x].l=l;t[x].r=r;
     65     t[x].lc=t[x].rc=0;
     66     t[x].cnt=0;t[x].len=0;
     67     t[x].rl=num[r+1]-num[l];
     68     if(l<r)
     69     {
     70         int mid=(l+r)/2;
     71         t[x].lc=bt(l,mid);
     72         t[x].rc=bt(mid+1,r);
     73     }
     74     return x;
     75 }
     76 
     77 void upd(int x)
     78 {
     79     int lc=t[x].lc,rc=t[x].rc;
     80     if(t[x].cnt>=1) t[x].len=t[x].rl;
     81     else t[x].len=t[lc].len+t[rc].len;
     82 }
     83 
     84 void change(int x,int l,int r,int d)
     85 {
     86     if(t[x].l==l && t[x].r==r) 
     87     {
     88         t[x].cnt+=d;
     89         upd(x);
     90         return;
     91     }
     92     int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/2;
     93     if(r<=mid) change(lc,l,r,d);
     94     else if(l>mid) change(rc,l,r,d);
     95     else
     96     {
     97         change(lc,l,mid,d);
     98         change(rc,mid+1,r,d);
     99     }
    100     upd(x);
    101 }
    102 
    103 void output()
    104 {
    105     for(int i=1;i<=tl;i++)
    106         printf("l = %d  r = %d  cnt = %d  len  = %lf  rl = %lf 
    ",t[i].l,t[i].r,t[i].cnt,t[i].len,t[i].rl);
    107 }
    108 
    109 int main()
    110 {
    111     freopen("a.in","r",stdin);
    112     while(scanf("%d",&n)!=EOF)
    113     {
    114         LL pre,ans,now;ans=0;pl=0;
    115         for(int i=1;i<=n;i++)
    116         {
    117             for(int j=0;j<=3;j++)
    118             {
    119                 scanf("%d",&z[i][j]);
    120                 inp(i,j,z[i][j]);
    121             }
    122         }
    123         unique();
    124         for(int k=0;k<=1;k++)
    125         {
    126             if(k==1)
    127             {
    128                 for(int i=1;i<=n;i++) swap(z[i][0],z[i][1]),swap(z[i][2],z[i][3]);    
    129             }
    130             make_edge();
    131             sort(a+1,a+1+al,cmp_y);
    132             tl=0;bt(1,mx-1);
    133             pre=0;
    134             for(int i=1;i<=al;i++)
    135             {
    136                 change(1,a[i].x1,a[i].x2-1,a[i].d);
    137                 now=t[1].len;
    138                 ans+=myabs(now-pre);
    139                 pre=now;
    140             }
    141             // printf("ans = %d
    ",ans);
    142         }
    143         printf("%lld
    ",ans);    
    144     }
    145     return 0;
    146 }
  • 相关阅读:
    Android必学——AsyncTask
    成员变量 局部变量
    Java中private、protected、public和default的区别
    实现图片的一个轮转功能
    vmware14克隆后UUID相同的解决方法
    curl
    python3 configparser模块
    python2.7系统性能监控psutil模块
    mysql5.7.22tar包安装
    通过pip3安装ipython
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/6025519.html
Copyright © 2011-2022 走看看