poj 3277 线段树

  这道题搞了我好久啊。。。真的好久,心中的一个疙瘩!最后还是求助我们班的大牛,再上网看看别人写的。才弄出来。。不容易啊。不过和别人的对比之后,才发现自己的代码还是不够“美”。好好努力吧,孩子

 

#include <iostream>
#include <algorithm>
#include <fstream>

#define MAXN 40005

using namespace std;

struct seg_tre{
long long l,r;
long long h;
struct seg_tre* pLeft,* pRight;
}Tree[MAXN*3];

struct CNode{
long long l,r;
long long h;
}Node[MAXN];

long long nNodeCount=0;
long long x[MAXN*2];
long long nCount=0,i,n;

bool cmp(CNode a,CNode b){
return a.h<b.h;
}
int Mid(seg_tre *pRoot){
return (pRoot->l+pRoot->r)/2;
}

void Create(seg_tre *pRoot,long long l,long long r){
pRoot->l=l;
pRoot->r=r;
pRoot->h=0;
if(l+1>=r) return;
nNodeCount++;
pRoot->pLeft=Tree+nNodeCount;
nNodeCount++;
pRoot->pRight=Tree+nNodeCount;
Create(pRoot->pLeft,l,Mid(pRoot));
Create(pRoot->pRight,Mid(pRoot),r);
}

void Insert(seg_tre *pRoot,long long l,long long r,long long h){
if(pRoot->h>=h) return;
if(pRoot->l==l &&pRoot->r==r){
pRoot->h=h;
return;
}
if(pRoot->h>0 && pRoot->l+1<pRoot->r){
pRoot->pLeft->h=pRoot->pRight->h=pRoot->h;
pRoot->h=0;
}
if(l>=Mid(pRoot)){
Insert(pRoot->pRight,l,r,h);
}
else if(r<=Mid(pRoot)){
Insert(pRoot->pLeft,l,r,h);
}
else{
Insert(pRoot->pLeft,l,Mid(pRoot),h);
Insert(pRoot->pRight,Mid(pRoot),r,h);
}
}

long long find(long long value){
long long l=0;
long long r=nCount-1;
while(l<r){
long long mid=(l+r)/2;
if(x[mid]==value) return mid;
else if(x[mid]<value) l=mid+1;
else r=mid-1;
}
return l;
}

long long cal(seg_tre *pRoot){
if(pRoot->h>0)
return (long long)pRoot->h*(x[pRoot->r]-x[pRoot->l]);
if(pRoot->l+1>=pRoot->r) return 0;
else return cal(pRoot->pLeft)+cal(pRoot->pRight);
}

int main(){

freopen("acm.in","r",stdin);
scanf("%lld",&n);
for(i=0 ;i<n ;i++){
scanf("%lld%lld%lld",&Node[i].l,&Node[i].r,&Node[i].h);
x[nCount++]=Node[i].l;
x[nCount++]=Node[i].r;
}
sort(x,x+nCount);
nCount=unique(x,x+nCount)-x;
sort(Node,Node+n,cmp);
Create(Tree,0,nCount-1);
for(i=0 ;i<n ;i++){
Insert(Tree,find(Node[i].l),find(Node[i].r),Node[i].h);
}
printf("%lld\n",cal(Tree));

return 0;
}

 下面时别人的代码。很好!我的数据结构有个就是多余的。像人家那么简洁,多好

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
__int64 i,j,k,N,min,max;
__int64 sum;
__int64 num[1000000];
typedef struct{
__int64 l,r;
__int64 high;
} ac;
ac ln[1000000],old[80000];
bool cmp(__int64 a,__int64 b){
return a<b;
}
bool cmp1(ac a,ac b)
{
return a.high<b.high;
}
void build(__int64 s,__int64 t,__int64 step)
{
__int64 mid;
mid=(s+t)/2;
ln[step].l=s;
ln[step].r=t;
ln[step].high=0;
if(1+s<t)
{
build(s,mid,2*step);
build(mid,t,2*step+1);
}
}
void insert(__int64 s,__int64 t,__int64 step,__int64 hi)
{
if(s==ln[step].l&&t==ln[step].r)
{
// if(hi>ln[step].high)
ln[step].high=hi;
return ;
}
else
{
if(ln[step].high>0)
{
ln[2*step].high=ln[step].high;
ln[2*step+1].high=ln[step].high;
ln[step].high=-1;
}
}
__int64 mid=(ln[step].r+ln[step].l)/2;
if(mid>=t)
insert(s,t,step*2,hi);
else
if(s>=mid)
insert(s,t,step*2+1,hi);
else
{
insert(s,mid,2*step,hi);
insert(mid,t,step*2+1,hi);
}
}
void visit(__int64 step)
{
if(ln[step].high>0)
{
sum=sum+ln[step].high*(num[ln[step].r]-num[ln[step].l]);
return ;
}
if(ln[step].l+2>ln[step].r) return;
visit(2*step);
visit(2*step+1);
}
__int64 binarysearch(__int64 value)
{
__int64 low,hig,mid;
low=0;
hig=k-1;
while(low<=hig)
{
mid=(low+hig)/2;
if(num[mid]==value)
return mid;
else
if(num[mid]<value)
low=mid+1;
else
hig=mid-1;
}
return 0;
}
int main(){
// while(1){
scanf("%I64d",&N);
k=0;
for(i=0;i<N;i++)
{
scanf("%I64d %I64d %I64d",&old[i].l,&old[i].r,&old[i].high);
num[k++]=old[i].l;
num[k++]=old[i].r;
}
sort(num,num+k);
k=1;
for(i=1;i<2*N;i++)
if(num[i]!=num[i-1])
num[k++]=num[i];
build(0,k-1,1);
sort(old,old+N,cmp1);
for(i=0;i<N;i++)
{
insert(binarysearch(old[i].l),binarysearch(old[i].r),1,old[i].high);
}
sum=0;
visit(1);
printf("%I64d\n",sum);
return 0;
}




你可能感兴趣的:(poj)