洛谷P1856 [USACO5.5]矩形周长Picture

题目背景

墙上贴着许多形状相同的海报、照片。它们的边都是水平和垂直的。每个矩形图片可能部分或全部的覆盖了其他图片。所有矩形合并后的边长称为周长。

题目描述

编写一个程序计算周长。

如图1所示7个矩形。

如图2所示,所有矩形的边界。所有矩形顶点的坐标都是整数。

输入输出格式

输入格式:

 

输入文件的第一行是一个整数N(0<=N<5000),表示有多少个矩形。接下来N行给出了每一个矩形左下角坐标和右上角坐标(所有坐标的数值范围都在-10000到10000之间)。

 

输出格式:

 

输出文件只有一个正整数,表示所有矩形的周长。

 

输入输出样例

输入样例#1: 复制
7
-15 0 5 10
-5 8 20 25
15 -4 24 14
0 -6 16 4
2 15 10 22
30 10 36 20
34 0 40 16
输出样例#1: 复制
228


扫描线线段树

其实能够找到的一些题解的线段树都暴力的很,如果稍微数据强一点就能卡,但是这题数据实在是太弱了QAQ

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<vector>
  6 #define MAXN 5005
  7 #define MAXM 10005 
  8 #define X first
  9 #define Y second
 10 #define pii pair<int,int>
 11 using namespace std;
 12 int read(){
 13     int x=0,f=1;char ch=getchar();
 14     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
 15     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 16     return x*f;
 17 }
 18 struct Node{
 19     int L,R,p,b;
 20     Node(int p1=0,int p2=0,int p3=0,int p4=0){
 21         L=p1,R=p2,p=p3,b=p4;
 22     }
 23 };
 24 bool comp(const Node &p1,const Node &p2){
 25     if(p1.p!=p2.p){
 26         return (p1.p<p2.p);
 27     }
 28     else{
 29         return (p1.b>p2.b);
 30     }
 31 }
 32 int n;
 33 vector<Node> vx,vy;
 34 void init(){
 35     n=read();
 36     for(int i=1;i<=n;i++){
 37         int x1=read(),y1=read(),x2=read(),y2=read();
 38         x1+=10001,y1+=10001,x2+=10001,y2+=10001;
 39         vx.push_back(Node(x1,x2,y1,1));vx.push_back(Node(x1,x2,y2,-1));
 40         vy.push_back(Node(y1,y2,x1,1));vy.push_back(Node(y1,y2,x2,-1));
 41     }
 42     sort(vx.begin(),vx.end(),comp);sort(vy.begin(),vy.end(),comp);
 43     n=10000*2;
 44 }
 45 int dat[MAXM<<3],tag[MAXM<<3];
 46 void pushdown(int k){
 47     int lc=(k<<1),rc=(k<<1|1);
 48     dat[lc]+=tag[k],dat[rc]+=tag[k];
 49     tag[lc]+=tag[k],tag[rc]+=tag[k];
 50     tag[k]=0;
 51 }
 52 void pushup(int k){
 53     dat[k]=min(dat[k<<1],dat[k<<1|1]);
 54 }
 55 void add(int a,int b,int k,int L,int R,int x){
 56     if(b<=L||R<=a){
 57         return;
 58     }
 59     else if(a<=L&&R<=b){
 60         dat[k]+=x;
 61         tag[k]+=x;
 62     }
 63     else{
 64         if(tag[k]){
 65             pushdown(k);
 66         }
 67         add(a,b,k<<1,L,(L+R)>>1,x);
 68         add(a,b,k<<1|1,(L+R)>>1,R,x);
 69         pushup(k);
 70     }
 71 }
 72 int query(int a,int b,int k,int L,int R){
 73     if(b<=L||R<=a){
 74         return 0;
 75     }
 76     if(L+1==R){
 77         return (dat[k]?1:0);
 78     }
 79     else if(a<=L&&R<=b&&dat[k]){
 80         return R-L;
 81     }
 82     else{
 83         if(tag[k]){
 84             pushdown(k);
 85         }
 86         int lc=query(a,b,k<<1,L,(L+R)>>1);
 87         int rc=query(a,b,k<<1|1,(L+R)>>1,R);
 88         return (lc+rc);
 89     }
 90 }
 91 int Abs(int x){
 92     return (x>0?x:-x);
 93 }
 94 void solve(){
 95     int ans=0;
 96     for(int i=0;i<vx.size();i++){
 97         int x=vx[i].L,y=vx[i].R,b=vx[i].b;
 98         int cnt1=query(x,y,1,1,n+1);
 99         add(x,y,1,1,n+1,b);
100         int cnt2=query(x,y,1,1,n+1);
101         ans+=Abs(cnt1-cnt2);
102 //        printf("%d ",Abs(cnt1-cnt2));
103     }
104 //    printf("\n");
105     for(int i=0;i<vy.size();i++){
106         int x=vy[i].L,y=vy[i].R,b=vy[i].b;
107         int cnt1=query(x,y,1,1,n+1);
108         add(x,y,1,1,n+1,b);
109         int cnt2=query(x,y,1,1,n+1);
110         ans+=Abs(cnt1-cnt2);
111 //        printf("%d ",Abs(cnt1-cnt2));
112     }
113     printf("%d\n",ans);
114 }
115 int main()
116 {
117 //    freopen("data.in","r",stdin);
118 //    freopen("my.out","w",stdout);
119     init();
120     solve();
121     return 0;
122 }

 

posted @ 2017-11-10 15:10  white_hat_hacker  阅读(370)  评论(0编辑  收藏  举报