zoukankan      html  css  js  c++  java
  • HDU 1828 Picture (线段树:扫描线周长)

    依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长。

    容易发现,扫描线中的某一条横边对答案的贡献。

    其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值

    然后横着竖着都做一遍就行了

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #define N 10010
      5 #define ll long long
      6 using namespace std;
      7 
      8 int n,sz;
      9 int a[N],cnt[N<<2],sum[N<<2];
     10 struct SQU{
     11     int a1,b1,a2,b2;
     12 }q[N];
     13 struct node{
     14     int l,r,la,ra,h,f;
     15 }sc[N];
     16 int cmp1(node s1,node s2){
     17     if(s1.h!=s2.h) return s1.h<s2.h;
     18     else return s1.f>s2.f;
     19 }
     20 void pushup(int l,int r,int rt)
     21 {
     22     if(cnt[rt]>0) sum[rt]=a[r+1]-a[l];
     23     else if(l==r) sum[rt]=0;
     24     else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
     25 }
     26 void update(int L,int R,int l,int r,int rt,int w)
     27 {
     28     if(L<=l&&r<=R) 
     29     {
     30         cnt[rt]+=w;
     31         pushup(l,r,rt);
     32         return;
     33     }
     34     int mid=(l+r)>>1;
     35     if(L<=mid) update(L,R,l,mid,rt<<1,w);
     36     if(R>mid) update(L,R,mid+1,r,rt<<1|1,w);
     37     pushup(l,r,rt);
     38 }
     39 void clr()
     40 {
     41     memset(a,0,sizeof(a));
     42     memset(sc,0,sizeof(sc));
     43     memset(cnt,0,sizeof(cnt));
     44     memset(sum,0,sizeof(sum));
     45 }
     46 int solvex()
     47 {   
     48     int ans=0,lst=0;
     49     for(int i=1;i<=n;i++)
     50     {
     51         a[2*i-1]=q[i].a1,a[2*i]=q[i].a2;
     52         sc[2*i-1].l=q[i].a1,sc[2*i].l=q[i].a1;
     53         sc[2*i-1].r=q[i].a2,sc[2*i].r=q[i].a2;
     54         sc[2*i-1].h=q[i].b1,sc[2*i].h=q[i].b2;
     55         sc[2*i-1].f=1,sc[2*i].f=-1;
     56     }
     57     sort(a+1,a+2*n+1);
     58     sz=unique(a+1,a+2*n+1)-(a+1);
     59     sort(sc+1,sc+2*n+1,cmp1);
     60     for(int i=1;i<=2*n;i++)
     61     {
     62         int la=lower_bound(a+1,a+sz+1,sc[i].l)-a;
     63         int ra=lower_bound(a+1,a+sz+1,sc[i].r)-a;
     64         lst=sum[1];
     65         update(la,ra-1,1,sz,1,sc[i].f);
     66         ans+=abs(sum[1]-lst);
     67     }
     68     return ans;
     69 }
     70 int solvey()
     71 {
     72     int ans=0,lst=0;
     73     for(int i=1;i<=n;i++)
     74     {
     75         a[2*i-1]=q[i].b1,a[2*i]=q[i].b2;
     76         sc[2*i-1].l=q[i].b1,sc[2*i].l=q[i].b1;
     77         sc[2*i-1].r=q[i].b2,sc[2*i].r=q[i].b2;
     78         sc[2*i-1].h=q[i].a1,sc[2*i].h=q[i].a2;
     79         sc[2*i-1].f=1,sc[2*i].f=-1;
     80     }
     81     sort(a+1,a+2*n+1);
     82     sz=unique(a+1,a+2*n+1)-(a+1);
     83     sort(sc+1,sc+2*n+1,cmp1);
     84     for(int i=1;i<=2*n;i++)
     85     {
     86         int la=lower_bound(a+1,a+sz+1,sc[i].l)-a;
     87         int ra=lower_bound(a+1,a+sz+1,sc[i].r)-a;
     88         lst=sum[1];
     89         update(la,ra-1,1,sz,1,sc[i].f);
     90         ans+=abs(sum[1]-lst);
     91     }
     92     return ans;
     93 }
     94 
     95 int main()
     96 {
     97     //freopen("data.in","r",stdin);
     98     scanf("%d",&n);
     99     for(int i=1;i<=n;i++)
    100         scanf("%d%d%d%d",&q[i].a1,&q[i].b1,&q[i].a2,&q[i].b2);
    101     int ret=0;
    102     ret+=solvex();
    103     clr();
    104     ret+=solvey();
    105     printf("%d
    ",ret);
    106     return 0;
    107 }
  • 相关阅读:
    第二十三课:运算放大电路正反馈
    第二十二课:运算放大电路
    第二十课:运算放大器抽象
    第二十课:滤波器
    第十九课:阻抗模型(和第十八课重复)
    第十八颗:正弦稳态
    第十七课:二阶系统下,正弦稳态
    第十六课:二阶系统 上
    第十五课:存储与状态
    数据库 分布式事务 是 怎么 实现 的 ?
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9697021.html
Copyright © 2011-2022 走看看