Cod sursa(job #216489)

Utilizator zombie_testertest test zombie_tester Data 24 octombrie 2008 18:39:46
Problema Cutii Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.8 kb
# include <cstdio>
# include <vector>
# include <algorithm>

using namespace std;

# define FIN "cutii.in"
# define FOUT "cutii.out"
# define max(a,b) (a < b ? b : a)
# define min(a,b) (a < b ? a : b)
# define MAXN 3510
# define MAXK 8000

struct box
{
    int x,y,z;
} B[MAXN];

int N,T,i,j,k,rez,val,poz,ct = 0;
int Mx[MAXK];
int Mn[MAXK];
vector <int> Ai[MAXK];
vector <int> Ab[MAXK];

    int cmp(box A, box B)
    {
        return A.z < B.z;
    }
    
    void create(int nod,int st,int dr)
    {
        int mij,i;
        
        for (i = 1; i <= dr-st+3; ++i)
          {
             Ai[nod].push_back(0);
             Ab[nod].push_back(0);
             ct++;
          }
        if (st != dr)
          {
             mij = (st + dr) >> 1;
             create(nod<<1,st,mij);
             create(nod<<1|1,mij+1,dr);
          }
    }
    
    void Interclas(int nod,int st,int dr)
    {
        int n, m, mij, lf, rh;
        
        lf = nod << 1;  rh = lf | 1;
        
        mij = (st + dr) >> 1;
        n = mij - st + 1;
        m = dr - mij;
        
        Ai[lf][n + 1] = Ai[rh][m + 1] = MAXN;
        
        mij = m + n;
        m = n = 1;
        
        for (i = 1; i <= mij; ++i)
          {
            if (Ai[lf][n] < Ai[rh][m])
              Ai[nod][i] = Ai[lf][n++];
            else
              Ai[nod][i] = Ai[rh][m++];
            Ab[nod][i] = 0;
          }
    }
    
    void build(int nod,int st,int dr)
    {
        int mij, lf, rh;
        
        if (st == dr)
          {
             Mx[nod] = Mn[nod] = B[st].x;
             Ai[nod][1] = B[st].y;
             Ab[nod][1] = 0;
          }
        else
          {
              mij = (st + dr) >> 1;
              lf = nod << 1; rh = lf | 1;
              
              build(lf,st,mij);
              build(rh,mij+1,dr);
              
              Mx[nod] = max(Mx[lf],Mx[rh]);
              Mn[nod] = min(Mn[lf],Mn[rh]);
              Interclas(nod, st, dr);
          }
    }
    
    int search(int nod,int st,int dr,int val)
    {
        int mij, sol = 0;
        
        while (st <= dr)
          {
              mij = (st + dr) >> 1;
              
              if (Ai[nod][mij] < val)
                {
                   sol = mij;
                   st = mij + 1;
                }
              else dr = mij -1;
          }
        return sol;
    }
    
    void modify(int nod,int p,int N)
    {
        int i;
        
        for (i = p; i <= N; i += i^(i-1)&i)
          Ab[nod][i] = max(Ab[nod][i],val);
    }
    
    void update(int nod,int st,int dr)
    {
        int mij, lf, rh, p;
        
        if (st <= poz && poz <= dr)
          {
              p = search(nod,1,dr-st+1,B[poz].y);
              while (Ai[nod][p] < B[poz].y) p++;
              modify(nod,p,dr-st+1);
          }
        if (st != dr)
          {
              mij = (st + dr) >> 1;
              
              lf = nod << 1; rh = lf | 1;
              if (poz <= mij)
                update(lf,st,mij);
              else
                update(rh,mij+1,dr);
          }
    }
    
    int response(int nod,int p)
    {
         int i, sol = 0;
         
         for (i = p; i ; i -= i^(i-1)&i)
           sol = max(sol,Ab[nod][i]);
           
         return sol;
    }
    
    void query(int nod,int st,int dr)
    {
        int mij, lf, rh, p;
        
        if (Mx[nod] < B[poz].x)
          {
              p = search(nod,1,dr-st+1,B[poz].y);
              p = response(nod,p);
              val = max(val,p);
          }
        else
          {
              mij = (st + dr) >> 1;
              
              lf = nod << 1; rh = lf | 1;
              if (Mn[lf] < B[poz].x)
                query(lf,st,mij);
              if (Mn[rh] < B[poz].x)
                query(rh,mij+1,dr);
          }
    }

    int main()
    {
        freopen(FIN,"r",stdin);
        freopen(FOUT,"w",stdout);
        
        scanf("%d%d",&N,&T);
        
        create(1,1,N);
        
        for (k = 1; k <= T; ++k)
          {
              rez = 1;
          
              for (i = 1; i <= N; ++i)
                scanf("%d%d%d",&B[i].x,&B[i].y,&B[i].z);
                
              sort(B+1,B+N+1,cmp);
              
              build(1,1,N);
              
              val = 1; poz = 1;
              update(1,1,N);
              
              for (i = 2; i <= N; ++i)
                {
                    val = 0; poz = i;
                    query(1,1,N);
                    val++;
                    if (val > rez) rez = val;
                    update(1,1,N);
                }
                
              printf("%d\n",rez);
          }
        
        return 0;
    }