Cod sursa(job #137435)

Utilizator mastermageSchneider Stefan mastermage Data 17 februarie 2008 12:11:31
Problema Stalpi Scor 10
Compilator cpp Status done
Runda preONI 2008, Runda 4, Clasa a 10-a Marime 3.11 kb
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;

#define maxN 100

typedef long long lint;
struct st{
	int x,c,s,d;
	st(){}
	st(int xp,int cp,int sp,int dp){x=xp,c=cp,s=sp,d=dp;}
	bool operator<(st const&r)const{return x<r.x;}
};

struct arbint{
	struct nod{int pos; lint mn; nod*up,*l,*r;};
	nod*zeu;int sw;
	arbint(){zeu=0;sw=0;}
	
	void add(int pos,lint mn){
		if(!zeu){zeu=new nod; zeu->pos=pos; zeu->mn=mn; zeu->up=0; zeu->l=0; return; }
		nod*cur=zeu,*alt;
		while(cur->l){
			if(cur->r->pos <= pos)cur=cur->r;else cur=cur->l;
		}
		alt=cur;
		if(cur->pos > pos) sw=0;
		else{
			while(alt->up){
				if(alt->up->r!=alt){alt=alt->up->r;break;}
				alt=alt->up;
			}
			if(!alt->up)sw=1;else
			while(alt->l){
				alt=alt->l;
			}
		}
		
		if(cur->pos==pos){
			do{
				if(cur->mn > mn){
					cur->mn=mn;
					cur=cur->up;
				}else
					break;
			}while(cur);
			return;
		}
		
		nod*tat=new nod,*fiu=new nod;
		
		fiu->pos=pos; fiu->mn=mn; fiu->up=tat; fiu->l=0;
		
		if(sw){
			tat->pos=cur->pos; tat->mn=min(cur->mn,mn);
			tat->up=cur->up; tat->l=cur; tat->r=fiu;
			
			if(!cur->up){
				zeu=tat, cur->up=tat;
			}else{
				if(cur==cur->up->l)cur->up->l=tat;else cur->up->r=tat;
				cur->up=tat;
			}
			
			
		}else{
			cur=alt;
			
			tat->pos=pos; tat->mn=min(cur->mn,mn);
			tat->up=cur->up; tat->l=fiu; tat->r=cur;
			
			if(!cur->up){
				zeu=tat, cur->up=tat;
			}else{
				if(cur==cur->up->l)cur->up->l=tat;else cur->up->r=tat;
				cur->up=tat;
			}
			
		}
		
		cur=tat->up;
		while(cur){
			if(cur->mn > mn){
				cur->mn=mn;
				cur=cur->up;
			}else
				break;
		}
		
		cur=tat->up;
		while(cur){
			if(cur->pos > pos){
				cur->pos=pos;
				cur=cur->up;
			}else
				break;
		}
		
		sw^=1;
	}
	
	lint quer(int pos){
		lint res=0;nod*cur=zeu;
		
		while(cur->l){
			if(cur->pos >= pos)break;
			if(cur->r->pos >= pos){
				if(cur->r->mn <res || !res) res=cur->r->mn;
				cur=cur->l;
			}else{
				cur=cur->r;
			}
			
			
		}
		if(cur->pos >= pos){
				if(cur->mn < res || !res)res=cur->mn;
		}
		return res;
	}
	
};


int n;
st vec[maxN];
lint res,din[maxN],dinf[maxN];

void inputFunc(){
	FILE*fi=fopen("stalpi.in","r");
	fscanf(fi,"%d",&n);
	for(int i=0;i<n;i++){
		int x,c,s,d;
		fscanf(fi,"%d %d %d %d",&x,&c,&s,&d);
		vec[i]=st(x,c,x-s,x+d);
	}
	fclose(fi);
}

int bs(int x){
	int s=0,e=n,m;
	while(s<e){
		m=s+e>>1;
		if(vec[m].x < x){
			s=m+1;
		}else{
			e=m;
		}
	}
	return s;
}

void outputFunc(){FILE*fi=fopen("stalpi.out","w");fprintf(fi,"%lld",res);fclose(fi);}

int main(){
	inputFunc();
	sort(vec,vec+n);
	
	arbint tr;
	
	din[0]=dinf[0]=vec[0].c; tr.add(vec[0].d,vec[0].c);
	
	for(int i=1;i<n;i++){
		lint cur=vec[i].c,alt;
		int p=bs(vec[i].s);
		if(vec[p].x>=vec[i].s)p--;
		if(p>=0){
			int mn=din[p];
			for(int j=p;j<i;j++)if(mn>din[j])mn=din[j];
			cur+=mn;
		}
		
		dinf[i]=cur;
		
		alt=tr.quer(vec[i].x);
		tr.add(vec[i].d,cur);
		
		if(alt && alt<cur)cur=alt;
		din[i]=cur;
	}
	
	res=din[n-1];
	outputFunc();
	return 0;
}