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 }
  • 相关阅读:
    jQuery EasyUI API 中文文档 可调整尺寸
    jQuery EasyUI API 中文文档 链接按钮(LinkButton)
    jQuery EasyUI API 中文文档 手风琴(Accordion)
    jQuery EasyUI API 中文文档 表单(Form)
    jQuery EasyUI API 中文文档 组合(Combo)
    jQuery EasyUI API 中文文档 布局(Layout)
    jQuery EasyUI API 中文文档 拆分按钮(SplitButton)
    jQuery EasyUI API 中文文档 菜单按钮(MenuButton)
    jQuery EasyUI API 中文文档 搜索框
    jQuery EasyUI API 中文文档 验证框(ValidateBox)
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9697021.html
Copyright © 2011-2022 走看看