codevs3044 线段树+扫描线
Posted blues
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs3044 线段树+扫描线相关的知识,希望对你有一定的参考价值。
1 // #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <sstream> 6 #include <string> 7 #include <algorithm> 8 #include <list> 9 #include <map> 10 #include <vector> 11 #include <queue> 12 #include <stack> 13 #include <cmath> 14 #include <cstdlib> 15 // #include <conio.h> 16 using namespace std; 17 #define clc(a,b) memset(a,b,sizeof(a)) 18 #define inf 0x3f3f3f3f 19 #define lson l,mid,rt<<1 20 #define rson mid+1,r,rt<<1|1 21 const int N = 1100; 22 const int MOD = 1e9+7; 23 #define LL long long 24 #define mi() (l+r)>>1 25 double const pi = acos(-1); 26 27 // inline int r() { 28 // int x=0,f=1;char ch=getchar(); 29 // while(ch>\'9\'||ch<\'0\') {if(ch==\'-\') f=-1;ch=getchar();} 30 // while(ch>=\'0\'&&ch<=\'9\') { x=x*10+ch-\'0\';ch=getchar();}return x*f; 31 // } 32 int n; 33 double hashh[N<<2]; 34 double sum[N<<2]; 35 int color[N<<2]; 36 struct Edge{ 37 double x1,x2,y; 38 int flag; 39 bool operator < (const Edge &a) const{ 40 return y<a.y; 41 } 42 }e[N<<2]; 43 44 int b_s(double x){ 45 int l=1,r=2*n; 46 int mid; 47 while(l<=r){ 48 mid=(l+r)>>1; 49 if(hashh[mid]==x) return mid; 50 else if(hashh[mid]<x) l=mid+1; 51 else r=mid-1; 52 } 53 } 54 55 void pushdown(int rt,int l,int r){ 56 if(color[rt]) sum[rt]=hashh[r+1]-hashh[l]; 57 else if(l==r) sum[rt]=0; 58 else sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 59 } 60 61 void update(int l,int r,int rt,int x,int y,int f){ 62 if(x==l&&y==r){ 63 color[rt]+=f; 64 pushdown(rt,l,r); 65 return; 66 } 67 int mid=mi(); 68 if(y<=mid) update(l,mid,rt<<1,x,y,f); 69 else if(x>mid) update(mid+1,r,rt<<1|1,x,y,f); 70 else { 71 update(l,mid,rt<<1,x,mid,f); 72 update(mid+1,r,rt<<1|1,mid+1,y,f); 73 } 74 pushdown(rt,l,r); 75 } 76 int main(){ 77 // int n; 78 while(scanf("%d",&n)){ 79 if(n==0) 80 break; 81 clc(color,0); 82 clc(sum,0); 83 double x1,x2,y1,y2; 84 for(int i=1;i<=n;i++){ 85 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 86 e[i*2-1].x1=e[i*2].x1=x1; 87 e[i*2-1].x2=e[i*2].x2=x2; 88 e[i*2-1].y=y1;e[i*2].y=y2; 89 e[i*2-1].flag=1;e[i*2].flag=-1; 90 hashh[i*2-1]=x1;hashh[i*2]=x2; 91 } 92 sort(e+1,e+1+2*n); 93 sort(hashh+1,hashh+1+2*n); 94 double ans=0; 95 for(int i=1;i<=2*n;i++){ 96 int l=b_s(e[i].x1),r=b_s(e[i].x2)-1; 97 // cout<<"l:"<<l<<" "<<"r:"<<r<<endl; 98 if(l<=r) update(1,2*n,1,l,r,e[i].flag); 99 // cout<<"sum[1]"<<sum[1]<<endl; 100 ans+=sum[1]*(e[i+1].y-e[i].y); 101 } 102 printf("%.2f\\n",ans); 103 } 104 return 0; 105 }
以上是关于codevs3044 线段树+扫描线的主要内容,如果未能解决你的问题,请参考以下文章