Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

过了3个月,我自己解决了~~~~~~~

Posted by ccyjava at 2010-12-01 18:00:31 on Problem 1177
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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator