zoukankan      html  css  js  c++  java
  • [51nod1206]Picture

      给你一坨矩形,问这些矩形组成的所有多边形的周长之和。

      分别求竖着的边和横着的边。

      离散化后线段树,维护当前行(或者列)有多少没在多边形里的,添加矩形就变成添加、删除线段。

      每次加线段或删线段时累加一下贡献(加线段时的贡献就是加完后那条线段里有多少个位置变成在多边形里,删线段时的贡献就是删完后有多少个位置变成不在多边形里)。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #define ll long long
     9 #define ull unsigned long long
    10 #define d double
    11 using namespace std;
    12 const int maxn=100233,mxnode=maxn*50;
    13 struct zs{int h,l,r;bool add;}b[maxn];int n1;
    14 struct mat{int x1,y1,x2,y2;}a[50023];
    15 int lc[mxnode],rc[mxnode],mn[mxnode],num[mxnode],add[mxnode],tot,MX;
    16 int i,j,k,n,m,L,R,V;
    17 ll ans;
    18 
    19 int ra,fh;char rx;
    20 inline int read(){
    21     rx=getchar(),ra=0,fh=1;
    22     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
    23     if(rx=='-')fh=-1,rx=getchar();
    24     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
    25 }
    26 
    27 inline void ins(int &x,int l){x=++tot,mn[x]=add[x]=0,num[x]=l;}
    28 inline void upd(int x){
    29     int l=lc[x],r=rc[x];
    30     if(mn[l]>mn[r])swap(l,r);
    31     if(mn[l]==mn[r])mn[x]=mn[l]+add[x],num[x]=num[l]+num[r];
    32     else mn[x]=mn[l]+add[x],num[x]=num[l];
    33 }
    34 void insert(int x,int a,int b){
    35 //    printf("insert:%d--%d      %d-----%d
    ",a,b,L,R);
    36     if(L<=a&&R>=b){add[x]+=V,mn[x]+=V;return;}
    37     int mid=a+b>>1;
    38     if(!lc[x])ins(lc[x],mid-a+1);if(!rc[x])ins(rc[x],b-mid);
    39     if(L<=mid)insert(lc[x],a,mid);
    40     if(R>mid)insert(rc[x],mid+1,b);
    41     upd(x);//printf("%d--%d  mn:%d   num:%d
    ",a,b,mn[x],num[x]);
    42 }
    43 
    44 inline int get0(){return mn[1]!=0?0:num[1];}
    45 bool cmp(zs a,zs b){return a.h<b.h||(a.h==b.h&&a.add);}
    46 inline void calc(){
    47     int i;
    48     sort(b+1,b+1+n1,cmp);
    49     for(i=1;i<=tot;i++)lc[i]=rc[i]=0;tot=1,mn[1]=add[1]=0,num[1]=MX;
    50     for(i=1;i<=n1;i++){
    51         L=b[i].l,R=b[i].r;
    52         if(b[i].add)ans+=get0(),V=1,insert(1,1,MX),ans-=get0();
    53         else ans-=get0(),V=-1,insert(1,1,MX),ans+=get0();//printf("num0:%d    mn:%d
    ",get0(),mn[1]);
    54     }//printf("  ans:%d
    ",ans);
    55 }
    56 
    57 inline int abs1(int x){return x<0?-x:x;}
    58 inline int max(int a,int b){return a>b?a:b;}
    59 int main(){
    60     n=read();int tmp;
    61     for(i=1;i<=n;i++){
    62         a[i].x1=read(),a[i].y1=read(),a[i].x2=read()-1,a[i].y2=read()-1;
    63         tmp=max(max(abs1(a[i].x1),abs1(a[i].x2)),max(abs1(a[i].y1),abs1(a[i].y2)));
    64         if(tmp>MX)MX=tmp;
    65     }
    66     for(i=1;i<=n;i++)a[i].x1+=MX+1,a[i].x2+=MX+1,a[i].y1+=MX+1,a[i].y2+=MX+1;
    67     MX=MX<<1|1;
    68     n1=0;
    69     for(i=1;i<=n;i++)
    70         b[++n1]=(zs){a[i].x1,a[i].y1,a[i].y2,1},
    71         b[++n1]=(zs){a[i].x2+1,a[i].y1,a[i].y2,0};
    72     calc();
    73     n1=0;
    74     for(i=1;i<=n;i++)
    75         b[++n1]=(zs){a[i].y1,a[i].x1,a[i].x2,1},
    76         b[++n1]=(zs){a[i].y2+1,a[i].x1,a[i].x2,0};
    77     calc();
    78     printf("%lld
    ",ans);
    79 }
    View Code
  • 相关阅读:
    [转]html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
    [转]html5 Canvas画图教程(5)—canvas里画曲线之arc方法
    [转]html5 Canvas画图4:填充和渐变
    [转]html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
    [转]html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
    【Java进阶】Maven 简介
    【Java入地】Spring 的 作用域 & MVC & SSM
    【Linux】Kali 物理机安装笔记、简单过程及注意事项
    【电脑维修】 显卡错误(错误代码:43)
    【Linux】 编程环境搭建 JDK、Node.js、Npm、Yarn、Redis、Maven的安装与搭建
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5942477.html
Copyright © 2011-2022 走看看