题目背景
墙上贴着许多形状相同的海报、照片。它们的边都是水平和垂直的。每个矩形图片可能部分或全部的覆盖了其他图片。所有矩形合并后的边长称为周长。
题目描述
编写一个程序计算周长。
如图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(" "); 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 ",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 }