Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
过了3个月,我自己解决了~~~~~~~In Reply To:郁闷,一直WA,用线段树写的,我知道哪组数据过不了,但不知道原因,求人分析代码,有详细的注释~~~跪求~~ Posted by:ccyjava at 2010-10-13 15:08:12 我终于自己发现哪里错了~~~ 这个题目是涉及到点,线段树处理的是段,要变换一下。。。 看了N久线段树,终于知道一般的线段树怎么写了~~~~~ 代码如下 #include "stdio.h" #include "math.h" #include "algorithm" using namespace std; struct { int l,r; int cnt; int line; int lb,rb; int sum; int getmid(){ return (l+r)/2; } }st[30000];//横线段的线段树 struct SS{ int l,r; int h; int s; }ss[15000];//横线段 int pos[15000];//横坐标 int k;//横坐标的个数 int bin(int c); bool cmp(struct SS&a,struct SS&b){ return a.h<b.h; } void build(int a,int b,int ind){ st[ind].l=a; st[ind].r=b; st[ind].cnt=0; st[ind].sum=0; st[ind].line=0; st[ind].lb=st[ind].rb=0; if(a==b) return ; int mid=st[ind].getmid(); build(a,mid,ind*2); build(mid+1,b,ind*2+1); } void update(int ind){ if(st[ind].cnt){ st[ind].sum=pos[st[ind].r+1]-pos[st[ind].l];//在计算和时,还原点值,所以+1 }else if(st[ind].l==st[ind].r){ st[ind].sum=0; } else{ st[ind].sum=st[ind*2].sum+st[ind*2+1].sum; } } void updateline(int ind){ if(st[ind].cnt) st[ind].lb=st[ind].rb=st[ind].line=1; else if(st[ind].l==st[ind].r) st[ind].lb=st[ind].rb=st[ind].line=0; else{ st[ind].lb=st[ind*2].lb; st[ind].rb=st[ind*2+1].rb; st[ind].line=st[ind*2].line+st[ind*2+1].line-st[ind*2].rb*st[ind*2+1].lb; } } void insert(int a,int b,int c,int ind){ if(a<=st[ind].l&&st[ind].r<=b){ st[ind].cnt+=c; }else{ int mid=st[ind].getmid(); if(a<=mid) insert(a,b,c,ind*2); if(b>mid) insert(a,b,c,ind*2+1); } update(ind); updateline(ind); } int bin(int c){ int p,q; p=0; q=k-1; while(p<=q){ int mid=(p+q)/2; if(pos[mid]==c) return mid; if(pos[mid]<c) p=mid+1; else q=mid-1; } return -1; } int main(){ int n,m; int x1,x2; int cx=-1; scanf("%d",&n); cx++; int i,j; m=0; for(i=0;i<n;i++){ int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); pos[m]=ss[m].l=ss[m+1].l=a; ss[m].h=b; ss[m].s=1; pos[m+1]=ss[m].r=ss[m+1].r=c; ss[m+1].h=d; ss[m+1].s=-1; m+=2; } sort(pos,pos+m); sort(ss,ss+m,cmp); for(i=0,k=0;i<m;i++){ if(i==0||pos[i]!=pos[i-1]){ pos[k++]=pos[i]; } } build(0,k-1,1); int ret=0; int last=0; for(i=0;i<m-1;i++){ x1=bin(ss[i].l); x2=bin(ss[i].r)-1;//求出离散化后的点对应的序号,换成段的序号要-1 if(x2<x1){//两个点重复时,特殊处理! ret+=abs(st[1].sum-last); ret+=(st[1].line*2*(ss[i+1].h-ss[i].h)); last=st[1].sum; continue; } insert(x1,x2,ss[i].s,1); ret+=abs(st[1].sum-last); ret+=(st[1].line*2*(ss[i+1].h-ss[i].h)); last=st[1].sum; } ret+=st[1].sum; printf("%d\n",ret); return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator