标签:his img write ons tac 原来 分享图片 online test
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 17606 Accepted Submission(s): 7154
#include <map> #include <set> #include <cmath> #include <ctime> #include <stack> #include <queue> #include <cstdio> #include <cctype> #include <bitset> #include <string> #include <vector> #include <cstring> #include <iostream> #include <algorithm> #include <functional> #define fuck(x) cout<<"["<<x<<"]"; #define FIN freopen("input.txt","r",stdin); #define FOUT freopen("output.txt","w+",stdout); #pragma comment(linker, "/STACK:102400000,102400000") #define clr(x) memset(x,0,sizeof(x)); using namespace std; const int maxn 105+5; struct segment//保存矩形的上下边 { double l,r,h;//左右横坐标,纵坐标 int f;//1为下边界,-1为上边界 segment() {}; segment(double x1,double x2,double y,int ic) { l=x1,r=x2,h=y,f=ic; } bool operator < (const segment&A)const//按高度从小到大排序 { return h<A.h; } } p[maxn]; struct node{ int le,ri; int cnt;//该节点被覆盖的情况 double len;//该区间被覆盖的总长度 int mid() { return (le+ri)>>1; } } tree[maxn<<2]; double pos[maxn]; void Build(int rt,int le,int ri){ tree[rt].le=le; tree[rt].ri=ri; tree[rt].len=0; tree[rt].cnt=0; if(le==ri) return ; int mid=tree[rt].mid(); Build(rt<<1,le,mid); Build(rt<<1|1,mid+1,ri); } void Upfather(int rt){ //计算长度的时候需要把原来的点+1,因为要算这一段的长度 if(tree[rt].cnt)//非0,已经被整段覆盖 //计算节点的长度 tree[rt].len=pos[tree[rt].ri+1]-pos[tree[rt].le]; else if(tree[rt].le==tree[rt].ri)//已经不是一条线段 tree[rt].len=0; else//是一条线段但是又没有整段覆盖,那么只能从左右孩子的信息中获取 tree[rt].len=tree[rt<<1].len+tree[rt<<1|1].len; } void Update(int rt,int val,int left,int right){ if(left<=tree[rt].le&&tree[rt].ri<=right) { tree[rt].cnt+=val;//更新这个区间被覆盖的情况 Upfather(rt);//更新这个区间被覆盖的总长度 return ; } int mid=tree[rt].mid(); if(left<=mid) Update(rt<<1,val,left,right); if(right>mid) Update(rt<<1|1,val,left,right); Upfather(rt);//计算该区间被覆盖的总长度 } int Search(int le,int ri,double k){ while(le<=ri) { int mid=(le+ri)>>1; if(pos[mid]==k) return mid; else if(pos[mid]>k) ri=mid-1; else le=mid+1; } } int main(){ #ifndef ONLINE_JUDGE FIN #endif int n,k=0; double x1,x2,y1,y2; while(~scanf("%d",&n),n){ int tot=0; for(int i=0; i<n; ++i){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); pos[tot]=x1; p[tot++]=segment(x1,x2,y1,1);//记录下边界的信息 pos[tot]=x2; p[tot++]=segment(x1,x2,y2,-1);//记录上边界的信息 } sort(pos,pos+tot);//横坐标升序排序 sort(p,p+tot);//按高度排序 int m=1; for(int i=1; i<tot; ++i)//去重 if(pos[i]!=pos[i-1]) pos[m++]=pos[i]; Build(1,0,m-1);//离散化后的区间就是[0,m-1],以此建树 double ans=0; // cout<<tot<<endl; // cout<<m<<endl; for(int i=0; i<tot; ++i)//拿出每条横线并且更新 { //线段树记录的是点 //所以每个点的查询从0开始,后面每个坐标要 -1 //树上的节点的区间 int le=Search(0,m-1,p[i].l); //线段左边坐标 int ri=Search(0,m-1,p[i].r)-1; //线段右边坐标 //cout<<le<<"------"<<ri<<endl; Update(1,p[i].f,le,ri); ans+。=tree[1].len*(p[i+1].h-p[i].h);//求面积 } printf("Test case #%d\nTotal explored area: %.2f\n",++k,ans); puts(""); } return 0; }
标签:his img write ons tac 原来 分享图片 online test
原文地址:https://www.cnblogs.com/buerdepepeqi/p/9374605.html