Cod sursa(job #471927)

Utilizator APOCALYPTODragos APOCALYPTO Data 21 iulie 2010 19:19:37
Problema Nums Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.33 kb
// Problema Nums ONI 2008 - baraj

// (c) Mircea Dima

#include <cstdio>
#include <vector>
#define oo 0x3f3f3f3f

using namespace std;


struct nod
{
    int nr;
    bool end;
    nod *next[10];

};

struct nodtreap
{
    int v, p;

    int nr;
    nodtreap *l,*r;

    nod *T;
};


typedef nodtreap* treap;

treap R, nil;


inline void init()
{
    nil=new nodtreap;
    nil->l=nil->r=0;
    nil->p=nil->v=-0x3f3f3f3f;
    nil->T=0;
    nil->nr=0;
    R=nil;
}

inline void getnr(treap &n)
{
    if(n == nil) return;

    
    n->nr=n->l->nr + n->r->nr + n->T->nr;
}

inline void rotleft(treap &n)
{
    treap t=n->l;
    n->l=t->r;
    t->r=n;
    getnr(n); getnr(t);
    n=t;
}

inline void rotright(treap &n)
{
    treap t=n->r;
    n->r=t->l;
    t->l=n;
    getnr(n); getnr(t);
    n=t;
}

inline void insert(treap &n, nod *&T, int len)
// inserarea in treap
{
    if(n == nil)
    {
	n=new nodtreap;
	n->l=n->r=nil;
	n->v=len;
	n->T=T;
	n->p=rand();//*rand();
	n->nr=T->nr;
	
	return;

    }

    if(len < n->v) 
    {
	insert(n->l, T, len);
	if(n->l->p > n->p) rotleft(n);
    }

    if(len > n->v)
    {
	insert(n->r, T, len);
	if(n->r->p > n->p) rotright(n);
    }

    getnr(n);
}

inline void update(treap &n, int len)
{
    if(n == nil) return;
    if(len < n->v) update(n->l, len);
    if(len > n->v) update(n->r, len);

    n->nr++;
}

inline nod* find(treap n, int len)
// cautare in treap
{
    if(n == nil) return (nod*) 0;
    if(len < n->v) return find(n->l, len);
    if(len > n->v) return find(n->r, len);
    return n->T;
}

char a[100024];






inline void findkth(treap n, int k)
// pe treap
{
    if(n == nil) return ;
    if(n->l->nr + n->T->nr >= k && n->l->nr < k) { afis(n->T, k - n->l->nr,0);return;}
    if(n->l->nr + n->T->nr < k)  findkth(n->r, k-(n->l->nr + n->T->nr));
    if(n->l->nr >= k)  findkth(n->l, k);

    return ;
}
int OK;
int n;


inline void insrt(nod *T, char a[], int i)
{
    if(i == n) {T->nr=1; T->end=1;return;}

    
    if(T->next[a[i]] == 0)
    {
	T->next[a[i]]=new nod;
	T->next[a[i]]->end=0;
	memset(T->next[a[i]]->next, 0,sizeof(T->next));
	//OKI=1;
	T->next[a[i]]->nr=0;
    }

    insrt(T->next[a[i]], a, i+1);

	//if(OKI)
     ++T->nr;    
       
}

inline int find(nod *T, char a[], int n)
{
	for(int i=0; i < n; ++i)
	{
		if(T->next[a[i]] == 0) return 0;
		T = T->next[a[i]];
	}
	
	if(T->end == 0) return 0;
	return 1;
	
}

inline void insert(char a[], int n)
{
    int i;
    for(i=0; i < n; ++i) a[i] -= '0';

    nod *t=find(R, n);

//    OKI=0;
	
    if(t == 0)
    {
	t=new nod;
	memset(t->next, 0, sizeof(t->next));
	t->nr=0;
	insrt(t, a,0);
	
	insert(R, t, n);

    }
    else
    {
	
		if(find(t, a, n) == 0)
		{
			
			
		insrt(t, a,0);

		update(R, n);
		}
    }


}




int N;
int main()
{

    init();
    int i;

    freopen("nums.in","r",stdin);
    freopen("nums.out","w",stdout);
    scanf("%d\n", &N);
   
    int type,k;
    while(N--)
    {
	scanf("%d ", &type);

	if(type == 1)
	{
	    scanf("%s\n", &a);
	    n=strlen(a);
	
	    insert(a, n);
	    memset(a, 0, sizeof(char)*(n+1));
	}
	
	if(type == 0)
	{
	    scanf("%d\n", &k);
	    findkth(R, k);

	}
    }


    return 0;
}