标签:测试 nio diff section 推荐 which sample 开始 main
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18559 Accepted Submission(s): 7523
#include<cstdio> #include<algorithm> using namespace std; const int N=100007; int t[N],a[N]; int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",a+i); t[i]=a[i]; } sort(t,t+n); int m=unique(t,t+n)-t;//共有每个不重复的元素 for(int i=0;i<n;i++) a[i]=lower_bound(t,t+m,a[i])-t+1;//从1开始编号 for(int i=0;i<n;i++) printf("%d ",a[i]);//测试输出 return 0; }
之前建线段树都是以某个点为叶子结点的,但是这次却不能这么写,而要以单位长度为叶子结点。
线段树主要维护cnt(-1表示覆盖不明确,>=0表示完全覆盖cnt次,模仿海报问题),len(区间长度,这就要求离散化的时候建立离散后的数值与原数值的映射)。
其他的参考那篇博客就好啦。
#include<cstdio> #include<algorithm> using namespace std; double t[410];//排序数组 double a[410];//原始数据 int b[410];//离散后的数据 double c[410];//离散后的数据到原数据的映射 struct tsegment { int x1,x2; int y; int flag; }; tsegment segment[210]; int cmp(tsegment a,tsegment b) { return a.y<b.y; } struct ttree { int l,r; int cover;//-1不确定 >=0完全覆盖次数 就不打tag了,时间可能会长点 double len;//区间长度 }; ttree tree[400*4+20]; void pushup(int x) { if(tree[x].l+1==tree[x].r) return; if(tree[x*2].cover==tree[x*2+1].cover&&tree[x*2].cover>=0) tree[x].cover=tree[x*2].cover; else tree[x].cover=-1; } void pushdown(int x) { if(tree[x].l+1==tree[x].r) return; if(tree[x].cover>=0) tree[x*2].cover=tree[x*2+1].cover=tree[x].cover; } void build(int x,int l,int r) { tree[x].l=l; tree[x].r=r; tree[x].len=c[r]-c[l]; tree[x].cover=0; if(l+1<r) { int mid=(l+r+1)/2; build(x*2,l,mid); build(x*2+1,mid,r);//叶子节点为一小段区间 } } void modify(int x,int l,int r,int flag) { if(l<=tree[x].l&&r>=tree[x].r&&tree[x].cover>=0) { tree[x].cover+=flag; //printf("%d %d\n",tree[x].l,tree[x].r); } else if(tree[x].l+1<tree[x].r) { pushdown(x); int mid=(tree[x].l+tree[x].r+1)/2; if(l<mid) modify(x*2,l,r,flag); if(r>mid) modify(x*2+1,l,r,flag); pushup(x); } } double query(int x) { if(tree[x].cover>0) return tree[x].len; else if(tree[x].cover==0) return 0; else { pushdown(x); double ret=0; ret+=query(x*2); ret+=query(x*2+1); return ret; } } int main() { int n,k=1; while(scanf("%d",&n),n) { for(int i=0;i<n*4;i++) { scanf("%lf",a+i); t[i]=a[i]; } sort(t,t+n*4); int m=unique(t,t+n*4)-t;//共有m个不同的数据 for(int i=0;i<n*4;i++) { b[i]=lower_bound(t,t+m,a[i])-t+1;//编号从1开始 c[b[i]]=a[i]; } //for(int i=1;i<=m;i++) printf("%f\n",c[i]); for(int i=0;i<n;i++) { int x1=b[i*4],y1=b[i*4+1]; int x2=b[i*4+2],y2=b[i*4+3]; segment[i*2].x1=x1;segment[i*2].x2=x2; segment[i*2].y=y1;segment[i*2].flag=1; segment[i*2+1].x1=x1;segment[i*2+1].x2=x2; segment[i*2+1].y=y2;segment[i*2+1].flag=-1; } sort(segment,segment+n*2,cmp); build(1,1,m); modify(1,segment[0].x1,segment[0].x2,segment[0].flag); double ans=0; for(int i=1;i<n*2;i++) { //printf("%.2f\n",query(1)); //printf("%d %d\n",segment[i].x1,segment[i].x2); ans=ans+query(1)*(c[segment[i].y]-c[segment[i-1].y]); modify(1,segment[i].x1,segment[i].x2,segment[i].flag); } printf("Test case #%d\nTotal explored area: %.2f\n\n",k++,ans); } return 0; }
标签:测试 nio diff section 推荐 which sample 开始 main
原文地址:https://www.cnblogs.com/acboyty/p/9532423.html