#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct no{
int pontuacao, id;
struct no *dir, *esq, *pai;
}No;
No *cria_no(int nova_pontuacao, int ID){
No
*novo
= malloc(sizeof(No
)); novo->pontuacao = nova_pontuacao;
novo->dir = novo->esq = NULL;
novo->id = ID;
novo->pai = NULL;
return novo;
}
No *insere_no(No *raiz, int nova_pontuacao, int ID){
No *pai_aux = NULL;
No *aux = NULL;
No *nova = cria_no(nova_pontuacao, ID);
if (raiz == NULL)
raiz = nova;
else
{
aux = raiz;
while (aux != NULL)
{
pai_aux = aux;
if (nova_pontuacao < aux->pontuacao)
aux = aux->esq;
else
aux = aux->dir;
}
nova->pai = pai_aux;
if (nova_pontuacao < pai_aux->pontuacao)
pai_aux->esq = nova;
else if(nova_pontuacao > pai_aux->pontuacao)
pai_aux->dir = nova;
else{
if(pai_aux == raiz){
aux = pai_aux;
raiz = nova;
raiz->dir = aux;
}
else{
aux = pai_aux;
pai_aux = nova;
pai_aux->dir = aux;
}
}
}
return raiz;
}
void em_ordem(No *raiz)
{
if (raiz != NULL)
{
em_ordem(raiz->esq);
printf("%d ", raiz
->pontuacao
); em_ordem(raiz->dir);
}
}
void pre_ordem(No *raiz)
{
if (raiz != NULL)
{
printf("%d ", raiz
->pontuacao
); pre_ordem(raiz->esq);
pre_ordem(raiz->dir);
}
}
No* sucessor(No *no_remover)
{
// por sucessor
No *suc = no_remover->dir;
while (suc->esq != NULL)
{
suc = suc->esq;
}
return suc;
}
No* antecessor(No *no_remover)
{
// por sucessor
No *ant = no_remover->esq;
while (ant->dir != NULL)
{
ant = ant->dir;
}
return ant;
}
No *remove_noavl(No *raiz, int chave)
{
No *no_remover = raiz;
No *pai_no_remover = NULL;
No *copia = NULL;
while (no_remover != NULL && no_remover->pontuacao != chave)
{
if (no_remover->pontuacao < chave)
no_remover = no_remover->dir;
else
no_remover = no_remover->esq;
}
while (no_remover != NULL) // encontrou o valor a ser removido
{
if (no_remover->esq == NULL && no_remover->dir == NULL)//eh folha
{
if (raiz == no_remover)
{
no_remover = raiz = NULL;
}
else
{
if (no_remover->pai->esq != NULL && no_remover->pai->esq->pontuacao == chave)
no_remover->pai->esq = NULL;
else
no_remover->pai->dir = NULL;
no_remover = NULL;
}
}
else // tem um filho ou dois filhos
{
if (no_remover->dir != NULL)
copia = sucessor(no_remover);
else
copia = antecessor(no_remover);
//substitui o valor da ser removido pelo valor
//do sucessor ou do antecessor
no_remover->pontuacao = copia->pontuacao;
no_remover->id = copia->id;
//muda o no a ser removido para o sucessor ou antecessor
no_remover = copia;
chave = copia->pontuacao;
}
}
return raiz;
}
No* registrar(No *raiz){
int pontuacao;
int id;
return insere_no(raiz, pontuacao, id);
}
int verifica_existencia(No*raiz, int id, int *pontuacao_velha, int*flag){
if(raiz != NULL && (*flag) != 1){
verifica_existencia(raiz->dir, id, pontuacao_velha, flag);
if(raiz->id == id){
(*flag) = 1;
(*pontuacao_velha) = raiz->pontuacao;
}
verifica_existencia(raiz->esq, id, pontuacao_velha, flag);
}
}
No* UPDATE(No *raiz){
int pontuacao_nova, pontuacao_velha, id, flag = 0;
scanf("%d", &pontuacao_nova
);
if(raiz != NULL){
verifica_existencia(raiz, id, &pontuacao_velha, &flag);
if(flag == 1){
raiz = remove_noavl(raiz, pontuacao_velha);
raiz = insere_no(raiz, pontuacao_nova, id);
}
}
return raiz;
}
int ID_MAX(No *raiz){
No* aux = raiz;
while(aux->esq != NULL)
aux = aux->esq;
return aux->id;
}
void posicao_calc(No *raiz, int id, int *CAT, int *flag){
if(raiz != NULL && (*flag) != 1){
posicao_calc(raiz->dir, id, CAT, flag);
if(raiz->id == id){
(*flag) = 1;
(*CAT)++;
}
else if((*flag) != 1){
(*CAT)++;
}
posicao_calc(raiz->esq, id, CAT, flag);
}
}
void posicao(No *raiz){
int id = 0;
if(raiz != NULL){
int rez_01, rez_02, aux_id, pos;
rez_01 = rez_02 = aux_id = pos = 0;
aux_id = ID_MAX(raiz);
posicao_calc(raiz, id, &rez_01, &pos);
pos = 0;
posicao_calc(raiz, aux_id, &rez_02, &pos);
if(rez_01>rez_02)
else
}
else{
}
}
void top(No *raiz){
if(raiz != NULL){
No* aux = raiz;
while(aux->dir != NULL)
aux = aux->dir;
}
else{
}
}
void BOTTOM(No *raiz){
if(raiz != NULL){
No* aux = raiz;
while(aux->esq != NULL)
aux = aux->esq;
}
else{
}
}
void RANGE_CALC(No *raiz, int pont_min, int pont_max){
if(raiz != NULL){
RANGE_CALC(raiz->dir, pont_min, pont_max);
if(pont_min <= raiz->pontuacao && raiz->pontuacao <= pont_max){
}
RANGE_CALC(raiz->esq, pont_min, pont_max);
}
}
void RANGE(No *raiz){
int min;
int max;
min = max = 0;
scanf("%d %d", &min
, &max
); if(raiz != NULL){
RANGE_CALC(raiz, min, max);
}
else
}
void COUNT_ABOVE(No *raiz, int ac, int* cont_0x){
if (raiz != NULL)
{
COUNT_ABOVE(raiz->dir, ac, cont_0x);
if(raiz->pontuacao > ac)
(*cont_0x)++;
COUNT_ABOVE(raiz->esq, ac, cont_0x);
}
}
void COUNT_BELOW(No *raiz, int ac, int* cont_0x){
if (raiz != NULL)
{
COUNT_BELOW(raiz->dir, ac, cont_0x);
if(raiz->pontuacao < ac)
(*cont_0x)++;
COUNT_BELOW(raiz->esq, ac, cont_0x);
}
}
int main(){
No *ABB = NULL;
int n, cont = 0;
int ac = 0;
int cont_02 = 0;
char rep[20];
while(cont < n){
if(strcmp(rep
, "REGISTER") == 0) ABB = registrar(ABB);
else if(strcmp(rep
, "UPDATE") == 0) ABB = UPDATE(ABB);
else if(strcmp(rep
, "POSITION") == 0) posicao(ABB);
else if(strcmp(rep
, "RANGE") == 0) RANGE(ABB);
else if(strcmp(rep
, "TOP") == 0) top(ABB);
else if(strcmp(rep
, "BOTTOM") == 0) BOTTOM(ABB);
else if(strcmp(rep
, "COUNT_ABOVE") == 0){ ac = cont_02 = 0;
COUNT_ABOVE(ABB, ac, &cont_02);
}
else if(strcmp(rep
, "COUNT_BELOW") == 0){ ac = cont_02 = 0;
COUNT_BELOW(ABB, ac, &cont_02);
}
cont++;
}
return 0;}
I2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKdHlwZWRlZiBzdHJ1Y3Qgbm97CiAgICBpbnQgcG9udHVhY2FvLCBpZDsKICAgIHN0cnVjdCBubyAqZGlyLCAqZXNxLCAqcGFpOwp9Tm87CgpObyAqY3JpYV9ubyhpbnQgbm92YV9wb250dWFjYW8sIGludCBJRCl7CiAgICBObyAqbm92byA9IG1hbGxvYyhzaXplb2YoTm8pKTsKICAgIG5vdm8tPnBvbnR1YWNhbyA9IG5vdmFfcG9udHVhY2FvOwogICAgbm92by0+ZGlyID0gbm92by0+ZXNxID0gTlVMTDsKICAgIG5vdm8tPmlkID0gSUQ7CiAgICBub3ZvLT5wYWkgPSBOVUxMOwogICAgcmV0dXJuIG5vdm87Cn0KCk5vICppbnNlcmVfbm8oTm8gKnJhaXosIGludCBub3ZhX3BvbnR1YWNhbywgaW50IElEKXsKICAgIE5vICpwYWlfYXV4ID0gTlVMTDsKICAgIE5vICphdXggPSBOVUxMOwogICAgTm8gKm5vdmEgPSBjcmlhX25vKG5vdmFfcG9udHVhY2FvLCBJRCk7CiAgICBpZiAocmFpeiA9PSBOVUxMKQogICAgICAgIHJhaXogPSBub3ZhOwogICAgZWxzZQogICAgewogICAgICAgIGF1eCA9IHJhaXo7CiAgICAgICAgd2hpbGUgKGF1eCAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgcGFpX2F1eCA9IGF1eDsKICAgICAgICAgICAgaWYgKG5vdmFfcG9udHVhY2FvIDwgYXV4LT5wb250dWFjYW8pCiAgICAgICAgICAgICAgICBhdXggPSBhdXgtPmVzcTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYXV4ID0gYXV4LT5kaXI7CiAgICAgICAgfQogICAgICAgIG5vdmEtPnBhaSA9IHBhaV9hdXg7CiAgICAgICAgaWYgKG5vdmFfcG9udHVhY2FvIDwgcGFpX2F1eC0+cG9udHVhY2FvKQogICAgICAgICAgICBwYWlfYXV4LT5lc3EgPSBub3ZhOwogICAgICAgIGVsc2UgaWYobm92YV9wb250dWFjYW8gPiBwYWlfYXV4LT5wb250dWFjYW8pCiAgICAgICAgICAgIHBhaV9hdXgtPmRpciA9IG5vdmE7CiAgICAgICAgZWxzZXsKICAgICAgICAgICAgaWYocGFpX2F1eCA9PSByYWl6KXsKICAgICAgICAgICAgICAgIGF1eCA9IHBhaV9hdXg7CiAgICAgICAgICAgICAgICByYWl6ID0gbm92YTsKICAgICAgICAgICAgICAgIHJhaXotPmRpciA9IGF1eDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgYXV4ID0gcGFpX2F1eDsKICAgICAgICAgICAgICAgIHBhaV9hdXggPSBub3ZhOwogICAgICAgICAgICAgICAgcGFpX2F1eC0+ZGlyID0gYXV4OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHJhaXo7Cn0KCnZvaWQgZW1fb3JkZW0oTm8gKnJhaXopCnsKICAgIGlmIChyYWl6ICE9IE5VTEwpCiAgICB7CiAgICAgICAgZW1fb3JkZW0ocmFpei0+ZXNxKTsKICAgICAgICBwcmludGYoIiVkICIsIHJhaXotPnBvbnR1YWNhbyk7CiAgICAgICAgZW1fb3JkZW0ocmFpei0+ZGlyKTsKICAgIH0KfQoKdm9pZCBwcmVfb3JkZW0oTm8gKnJhaXopCnsKICAgIGlmIChyYWl6ICE9IE5VTEwpCiAgICB7CiAgICAgICAgcHJpbnRmKCIlZCAiLCByYWl6LT5wb250dWFjYW8pOwogICAgICAgIHByZV9vcmRlbShyYWl6LT5lc3EpOwogICAgICAgIHByZV9vcmRlbShyYWl6LT5kaXIpOwogICAgfQp9CgpObyogc3VjZXNzb3IoTm8gKm5vX3JlbW92ZXIpCnsKCiAgICAvLyBwb3Igc3VjZXNzb3IKICAgIE5vICpzdWMgPSBub19yZW1vdmVyLT5kaXI7CgogICAgd2hpbGUgKHN1Yy0+ZXNxICE9IE5VTEwpCiAgICB7CiAgICAgICAgc3VjID0gc3VjLT5lc3E7CiAgICB9CgogICAgcmV0dXJuIHN1YzsKfQoKTm8qIGFudGVjZXNzb3IoTm8gKm5vX3JlbW92ZXIpCnsKCiAgICAvLyBwb3Igc3VjZXNzb3IKICAgIE5vICphbnQgPSBub19yZW1vdmVyLT5lc3E7CgogICAgd2hpbGUgKGFudC0+ZGlyICE9IE5VTEwpCiAgICB7CiAgICAgICAgYW50ID0gYW50LT5kaXI7CiAgICB9CgogICAgcmV0dXJuIGFudDsKfQoKTm8gKnJlbW92ZV9ub2F2bChObyAqcmFpeiwgaW50IGNoYXZlKQp7CgogICAgTm8gKm5vX3JlbW92ZXIgPSByYWl6OwogICAgTm8gKnBhaV9ub19yZW1vdmVyID0gTlVMTDsKICAgIE5vICpjb3BpYSA9IE5VTEw7CgogICAgd2hpbGUgKG5vX3JlbW92ZXIgIT0gTlVMTCAmJiBub19yZW1vdmVyLT5wb250dWFjYW8gIT0gY2hhdmUpCiAgICB7CiAgICAgICAgaWYgKG5vX3JlbW92ZXItPnBvbnR1YWNhbyA8IGNoYXZlKQogICAgICAgICAgICBub19yZW1vdmVyID0gbm9fcmVtb3Zlci0+ZGlyOwogICAgICAgIGVsc2UKICAgICAgICAgICAgbm9fcmVtb3ZlciA9IG5vX3JlbW92ZXItPmVzcTsKICAgIH0KCiAgICB3aGlsZSAobm9fcmVtb3ZlciAhPSBOVUxMKSAvLyBlbmNvbnRyb3UgbyB2YWxvciBhIHNlciByZW1vdmlkbwogICAgewogICAgICAgIGlmIChub19yZW1vdmVyLT5lc3EgPT0gTlVMTCAmJiBub19yZW1vdmVyLT5kaXIgPT0gTlVMTCkvL2VoIGZvbGhhCiAgICAgICAgewogICAgICAgICAgICBpZiAocmFpeiA9PSBub19yZW1vdmVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmcmVlKHJhaXopOwogICAgICAgICAgICAgICAgbm9fcmVtb3ZlciA9IHJhaXogPSBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKG5vX3JlbW92ZXItPnBhaS0+ZXNxICE9IE5VTEwgJiYgbm9fcmVtb3Zlci0+cGFpLT5lc3EtPnBvbnR1YWNhbyA9PSBjaGF2ZSkKICAgICAgICAgICAgICAgICAgICBub19yZW1vdmVyLT5wYWktPmVzcSA9IE5VTEw7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgbm9fcmVtb3Zlci0+cGFpLT5kaXIgPSBOVUxMOwoKICAgICAgICAgICAgICAgIGZyZWUobm9fcmVtb3Zlcik7CiAgICAgICAgICAgICAgICBub19yZW1vdmVyID0gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIC8vIHRlbSB1bSBmaWxobyBvdSBkb2lzIGZpbGhvcwogICAgICAgIHsKCiAgICAgICAgICAgIGlmIChub19yZW1vdmVyLT5kaXIgIT0gTlVMTCkKICAgICAgICAgICAgICAgIGNvcGlhID0gc3VjZXNzb3Iobm9fcmVtb3Zlcik7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGNvcGlhID0gYW50ZWNlc3Nvcihub19yZW1vdmVyKTsKCiAgICAgICAgICAgICAgICAvL3N1YnN0aXR1aSBvIHZhbG9yIGRhIHNlciByZW1vdmlkbyBwZWxvIHZhbG9yCiAgICAgICAgICAgICAgICAvL2RvIHN1Y2Vzc29yIG91IGRvIGFudGVjZXNzb3IKICAgICAgICAgICAgbm9fcmVtb3Zlci0+cG9udHVhY2FvID0gY29waWEtPnBvbnR1YWNhbzsKICAgICAgICAgICAgbm9fcmVtb3Zlci0+aWQgPSBjb3BpYS0+aWQ7CiAgICAgICAgICAgIC8vbXVkYSBvIG5vIGEgc2VyIHJlbW92aWRvIHBhcmEgbyBzdWNlc3NvciBvdSBhbnRlY2Vzc29yCiAgICAgICAgICAgIG5vX3JlbW92ZXIgPSBjb3BpYTsKICAgICAgICAgICAgY2hhdmUgPSBjb3BpYS0+cG9udHVhY2FvOwogICAgICAgIH0KICAgICAgICAKICAgIH0KICAgIHJldHVybiByYWl6Owp9CgpObyogcmVnaXN0cmFyKE5vICpyYWl6KXsKICAgIGludCBwb250dWFjYW87CiAgICBpbnQgaWQ7CiAgICBzY2FuZigiJWQiLCAmaWQpOwogICAgc2NhbmYoIiVkIiwgJnBvbnR1YWNhbyk7CiAgICByZXR1cm4gaW5zZXJlX25vKHJhaXosIHBvbnR1YWNhbywgaWQpOwp9CgppbnQgdmVyaWZpY2FfZXhpc3RlbmNpYShObypyYWl6LCBpbnQgaWQsIGludCAqcG9udHVhY2FvX3ZlbGhhLCBpbnQqZmxhZyl7CiAgICBpZihyYWl6ICE9IE5VTEwgJiYgKCpmbGFnKSAhPSAxKXsKICAgICAgICB2ZXJpZmljYV9leGlzdGVuY2lhKHJhaXotPmRpciwgaWQsIHBvbnR1YWNhb192ZWxoYSwgZmxhZyk7CiAgICAgICAgaWYocmFpei0+aWQgPT0gaWQpewogICAgICAgICAgICAoKmZsYWcpID0gMTsKICAgICAgICAgICAgKCpwb250dWFjYW9fdmVsaGEpID0gcmFpei0+cG9udHVhY2FvOwogICAgICAgIH0KICAgICAgICB2ZXJpZmljYV9leGlzdGVuY2lhKHJhaXotPmVzcSwgaWQsIHBvbnR1YWNhb192ZWxoYSwgZmxhZyk7CiAgICB9Cn0KCk5vKiBVUERBVEUoTm8gKnJhaXopewogICAgaW50IHBvbnR1YWNhb19ub3ZhLCBwb250dWFjYW9fdmVsaGEsIGlkLCBmbGFnID0gMDsKCiAgICBzY2FuZigiJWQiLCAmaWQpOwogICAgc2NhbmYoIiVkIiwgJnBvbnR1YWNhb19ub3ZhKTsKICAgIAogICAgaWYocmFpeiAhPSBOVUxMKXsKICAgICAgICB2ZXJpZmljYV9leGlzdGVuY2lhKHJhaXosIGlkLCAmcG9udHVhY2FvX3ZlbGhhLCAmZmxhZyk7CgogICAgICAgIGlmKGZsYWcgPT0gMSl7CiAgICAgICAgICAgIHJhaXogPSByZW1vdmVfbm9hdmwocmFpeiwgcG9udHVhY2FvX3ZlbGhhKTsKICAgICAgICAgICAgcmFpeiA9IGluc2VyZV9ubyhyYWl6LCBwb250dWFjYW9fbm92YSwgaWQpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByYWl6Owp9CgppbnQgSURfTUFYKE5vICpyYWl6KXsKICAgIE5vKiBhdXggPSByYWl6OwogICAgd2hpbGUoYXV4LT5lc3EgIT0gTlVMTCkKICAgICAgICBhdXggPSBhdXgtPmVzcTsKICAgIHJldHVybiBhdXgtPmlkOwp9Cgp2b2lkIHBvc2ljYW9fY2FsYyhObyAqcmFpeiwgaW50IGlkLCBpbnQgKkNBVCwgaW50ICpmbGFnKXsKICAgIGlmKHJhaXogIT0gTlVMTCAmJiAoKmZsYWcpICE9IDEpewogICAgICAgIHBvc2ljYW9fY2FsYyhyYWl6LT5kaXIsIGlkLCBDQVQsIGZsYWcpOwogICAgICAgIGlmKHJhaXotPmlkID09IGlkKXsKICAgICAgICAgICAgKCpmbGFnKSA9IDE7CiAgICAgICAgICAgICgqQ0FUKSsrOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKCgqZmxhZykgIT0gMSl7CiAgICAgICAgICAgICgqQ0FUKSsrOwogICAgICAgIH0KICAgICAgICBwb3NpY2FvX2NhbGMocmFpei0+ZXNxLCBpZCwgQ0FULCBmbGFnKTsKICAgIH0KfQoKdm9pZCBwb3NpY2FvKE5vICpyYWl6KXsKICAgIGludCBpZCA9IDA7CiAgICBzY2FuZigiJWQiLCAmaWQpOwogICAgCiAgICBpZihyYWl6ICE9IE5VTEwpewogICAgICAgIGludCByZXpfMDEsIHJlel8wMiwgYXV4X2lkLCBwb3M7CiAgICAgICAgcmV6XzAxID0gcmV6XzAyID0gYXV4X2lkID0gcG9zID0gMDsKCiAgICAgICAgYXV4X2lkID0gSURfTUFYKHJhaXopOwoKICAgICAgICBwb3NpY2FvX2NhbGMocmFpeiwgaWQsICZyZXpfMDEsICZwb3MpOwoKICAgICAgICBwb3MgPSAwOwoKICAgICAgICBwb3NpY2FvX2NhbGMocmFpeiwgYXV4X2lkLCAmcmV6XzAyLCAmcG9zKTsKCiAgICAgICAgaWYocmV6XzAxPnJlel8wMikKICAgICAgICAgICAgcHJpbnRmKCJOT1RfRk9VTkRcbiIpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcHJpbnRmKCIlZFxuIiwgcmV6XzAxKTsKICAgIH0KICAgIGVsc2V7CiAgICAgICAgcHJpbnRmKCJOT1RfRk9VTkRcbiIpOwogICAgfQogICAgCn0KCnZvaWQgdG9wKE5vICpyYWl6KXsKICAgIGlmKHJhaXogIT0gTlVMTCl7CiAgICAgICAgTm8qIGF1eCA9IHJhaXo7CiAgICAgICAgd2hpbGUoYXV4LT5kaXIgIT0gTlVMTCkKICAgICAgICAgICAgYXV4ID0gYXV4LT5kaXI7CiAgICAgICAgcHJpbnRmKCIlZFxuIiwgYXV4LT5pZCk7CiAgICB9CiAgICBlbHNlewogICAgICAgIHByaW50ZigiRU1QVFlcbiIpOwogICAgfQp9Cgp2b2lkIEJPVFRPTShObyAqcmFpeil7CiAgICBpZihyYWl6ICE9IE5VTEwpewogICAgICAgIE5vKiBhdXggPSByYWl6OwogICAgICAgIHdoaWxlKGF1eC0+ZXNxICE9IE5VTEwpCiAgICAgICAgICAgIGF1eCA9IGF1eC0+ZXNxOwogICAgICAgIHByaW50ZigiJWRcbiIsIGF1eC0+aWQpOwogICAgfQogICAgZWxzZXsKICAgICAgICBwcmludGYoIkVNUFRZXG4iKTsKICAgIH0KICAgIAp9Cgp2b2lkIFJBTkdFX0NBTEMoTm8gKnJhaXosIGludCBwb250X21pbiwgaW50IHBvbnRfbWF4KXsKICAgIGlmKHJhaXogIT0gTlVMTCl7CiAgICAgICAgUkFOR0VfQ0FMQyhyYWl6LT5kaXIsIHBvbnRfbWluLCBwb250X21heCk7CiAgICAgICAgaWYocG9udF9taW4gPD0gcmFpei0+cG9udHVhY2FvICYmIHJhaXotPnBvbnR1YWNhbyA8PSBwb250X21heCl7CiAgICAgICAgICAgIHByaW50ZigiJWQgIiwgcmFpei0+aWQpOwogICAgICAgIH0KICAgICAgICBSQU5HRV9DQUxDKHJhaXotPmVzcSwgcG9udF9taW4sIHBvbnRfbWF4KTsKICAgIH0KfQoKdm9pZCBSQU5HRShObyAqcmFpeil7CiAgICBpbnQgbWluOwogICAgaW50IG1heDsKICAgIG1pbiA9IG1heCA9IDA7CgogICAgc2NhbmYoIiVkICVkIiwgJm1pbiwgJm1heCk7CiAgICBpZihyYWl6ICE9IE5VTEwpewogICAgICAgIFJBTkdFX0NBTEMocmFpeiwgbWluLCBtYXgpOwogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KICAgIGVsc2UKICAgICAgICBwcmludGYoIkVNUFRZXG4iKTsKfQoKdm9pZCBDT1VOVF9BQk9WRShObyAqcmFpeiwgaW50IGFjLCBpbnQqIGNvbnRfMHgpewogICAgaWYgKHJhaXogIT0gTlVMTCkKICAgIHsKICAgICAgICBDT1VOVF9BQk9WRShyYWl6LT5kaXIsIGFjLCBjb250XzB4KTsKICAgICAgICBpZihyYWl6LT5wb250dWFjYW8gPiBhYykKICAgICAgICAgICAgKCpjb250XzB4KSsrOwogICAgICAgIENPVU5UX0FCT1ZFKHJhaXotPmVzcSwgYWMsIGNvbnRfMHgpOwogICAgfQp9Cgp2b2lkIENPVU5UX0JFTE9XKE5vICpyYWl6LCBpbnQgYWMsIGludCogY29udF8weCl7CiAgICBpZiAocmFpeiAhPSBOVUxMKQogICAgewogICAgICAgIENPVU5UX0JFTE9XKHJhaXotPmRpciwgYWMsIGNvbnRfMHgpOwogICAgICAgIGlmKHJhaXotPnBvbnR1YWNhbyA8IGFjKQogICAgICAgICAgICAoKmNvbnRfMHgpKys7CiAgICAgICAgQ09VTlRfQkVMT1cocmFpei0+ZXNxLCBhYywgY29udF8weCk7CiAgICB9Cn0KCmludCBtYWluKCl7CgpObyAqQUJCID0gTlVMTDsKaW50IG4sIGNvbnQgPSAwOwppbnQgYWMgPSAwOwppbnQgY29udF8wMiA9IDA7CmNoYXIgcmVwWzIwXTsKCnNjYW5mKCIlZCIsICZuKTsKCndoaWxlKGNvbnQgPCBuKXsKICAgIHN0cmNweShyZXAsIiAiKTsKICAgIGZmbHVzaChzdGRpbik7CiAgICBzY2FuZigiJXMiLCAmcmVwKTsKCiAgICBpZihzdHJjbXAocmVwLCAiUkVHSVNURVIiKSA9PSAwKQogICAgICAgIEFCQiA9IHJlZ2lzdHJhcihBQkIpOyAKICAgIGVsc2UgaWYoc3RyY21wKHJlcCwgIlVQREFURSIpID09IDApCiAgICAgICAgQUJCID0gVVBEQVRFKEFCQik7ICAgIAogICAgZWxzZSBpZihzdHJjbXAocmVwLCAiUE9TSVRJT04iKSA9PSAwKQogICAgICAgIHBvc2ljYW8oQUJCKTsKICAgIGVsc2UgaWYoc3RyY21wKHJlcCwgIlJBTkdFIikgPT0gMCkKICAgICAgICBSQU5HRShBQkIpOwogICAgZWxzZSBpZihzdHJjbXAocmVwLCAiVE9QIikgPT0gMCkKICAgICAgICB0b3AoQUJCKTsKICAgIGVsc2UgaWYoc3RyY21wKHJlcCwgIkJPVFRPTSIpID09IDApCiAgICAgICAgQk9UVE9NKEFCQik7CiAgICBlbHNlIGlmKHN0cmNtcChyZXAsICJDT1VOVF9BQk9WRSIpID09IDApewogICAgICAgIGFjID0gY29udF8wMiA9IDA7CiAgICAgICAgc2NhbmYoIiVkIiwgJmFjKTsKICAgICAgICBDT1VOVF9BQk9WRShBQkIsIGFjLCAmY29udF8wMik7CiAgICAgICAgcHJpbnRmKCIlZFxuIiwgY29udF8wMik7CiAgICB9CiAgICBlbHNlIGlmKHN0cmNtcChyZXAsICJDT1VOVF9CRUxPVyIpID09IDApewogICAgICAgIGFjID0gY29udF8wMiA9IDA7CiAgICAgICAgc2NhbmYoIiVkIiwgJmFjKTsKICAgICAgICBDT1VOVF9CRUxPVyhBQkIsIGFjLCAmY29udF8wMik7CiAgICAgICAgcHJpbnRmKCIlZFxuIiwgY29udF8wMik7CiAgICB9CiAgICBjb250Kys7Cn0KCnJldHVybiAwO30=