Cod sursa(job #138105)

Utilizator VmanDuta Vlad Vman Data 17 februarie 2008 21:10:36
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <stdio.h>
#include <string.h>

#define Nmax 100020
#define ll long long

struct stalp { int X,C,S,D; };

int N,Pmax,i,Ls,Ld;
stalp T[Nmax];
int st[Nmax],dr[Nmax],Q[Nmax];
ll cost[Nmax],m;
inline ll minim(ll a,ll b) { return a<b?a:b; }

void citire()
{
 freopen("stalpi.in","r",stdin);
 scanf("%d",&N);
 for (i=1;i<=N;++i)
      scanf("%d %d %d %d",&T[i].X,&T[i].C,&T[i].S,&T[i].D);
 fclose(stdin);
}

void qsort(int st,int dr)
{
 int i=st,j=dr,m=T[(st+dr)>>1].X;
 stalp aux;
 while (i<=j)
       {
        while (T[i].X<m) ++i;
        while (m<T[j].X) --j;
        if (i<=j)
           {
            aux=T[i]; T[i]=T[j]; T[j]=aux;
            ++i; --j;
           }
       }
 if (i<dr) qsort(i,dr);
 if (st<j) qsort(st,j);
}

void limite(int who)
{
 int p,rez;
 //cauta in stanga
 p=Pmax;
 rez=0;
 while (p)
       {
        if (T[rez+p].X < T[who].X - T[who].S) rez+=p;
        p>>=1;
        while (rez+p>N) p>>=1;
       }
 st[who]=rez+1;
 //cauta in dreapta
 p=Pmax;
 rez=0;
 while (p)
       {
        if (T[rez+p].X <= T[who].X + T[who].D) rez+=p;
        p>>=1;
        while (rez+p>N) p>>=1;
       }
 dr[who]=rez;
}

void qsortst(int Lst,int Ldr)
{
 int i=Lst,j=Ldr,m=st[(Lst+Ldr)>>1];
 int auxd;
 stalp aux;

 while (i<=j)
       {
        while (st[i]<m) ++i;
        while (m<st[j]) --j;
        if (i<=j)
           {
            aux=T[i]; T[i]=T[j]; T[j]=aux;
            auxd=st[i]; st[i]=st[j]; st[j]=auxd;
            auxd=dr[i]; dr[i]=dr[j]; dr[j]=auxd;
            ++i; --j;
           }
       }
 if (i<Ldr) qsortst(i,Ldr);
 if (Lst<j) qsortst(Lst,j);
}

void adauga(int who)
{
 int p=Ld,nr,i;
 while (cost[who]<cost[Q[p]] && p>=Ls) --p;
 while (cost[who]==cost[Q[p]] && dr[who]>dr[Q[p]] && p>=Ls) --p;
 ++p;
 for (i=Ld;i>=p;--i)
    Q[i+1]=Q[i];
 ++Ld;
 Q[p]=who;
 nr=p;
 for (i=p+1;i<=Ld;++i)
     if (dr[Q[i]]>dr[who])
        {
         ++nr;
         Q[nr]=Q[i];
        }
 Ld=nr;
}

void solve()
{
 //baga in dequeue toate felinarele care il acopera pe primul
 Q[Ls=Ld=1]=1;
 cost[1]=T[1].C;
 i=2;
 while (st[i]==1)
       {
        cost[i]=T[i].C;
        adauga(i);
        ++i;
       }
 while (i<=N)
       {
        while (dr[Q[Ls]]+1<st[i]) ++Ls;
        cost[i]=cost[Q[Ls]]+T[i].C;
        adauga(i);
        ++i;
       }
}

void dinamica()
{
 int i,j;
 cost[1]=T[1].C;
 for (i=2;i<=N;++i)
     {
      cost[i]=10000000000LL;
      if (st[i]==1) cost[i]=T[i].C;
         else
          for (j=1;j<i;++j)
              if (dr[j]+1>=st[i]) cost[i]=minim(cost[i],cost[j]+T[i].C);
     }
}

int main()
{
 freopen("stalpi.out","w",stdout);
 citire();
 qsort(1,N);
 Pmax=1;
 while ((Pmax<<1) <= N) Pmax<<=1;
 for (i=1;i<=N;++i)
      limite(i);
 //if (N<=1000) dinamica();
   // else
     //   {
         qsortst(1,N);
         solve();
       // }
 m=10000000000LL;
 for (i=1;i<=N;++i)
     if (dr[i]==N) m=minim(cost[i],m);
 printf("%lld",m);
 fclose(stdout);
 return 0;
}