Je suis bloqué pendant des heures sur la question de devoirs suivante pour la classe de structures de données:
On vous donne un ensemble statique S (c'est-à-dire que S ne change jamais) de n entiers de {1,. . . , u}.
Décrire une structure de données de taille O (n log u) qui peut répondre aux requêtes suivantes en O(1) time:
Empty(i, j)
- renvoie VRAI si et seulement s'il n'y a pas d'élément dans S entre i et j (où i et j sont des entiers dans {1,..., u}).
Au début, j'ai pensé à utiliser un y-fast-trie.
En utilisant y-fast-trie, nous pouvons obtenir O(n) espace et O(loglogu) requête (en trouvant le successeur de i et en vérifiant s'il est plus grand) que j).
Mais O(loglogu) n'est pas O (1) ...
Ensuite, j'ai pensé que nous pourrions peut-être trier le tableau et créer un deuxième tableau de taille n + 1 des plages qui ne sont pas dans le tableau, puis dans la requête, nous vérifierions si [i, j] est une sous-plage de l'un des les plages mais je n'ai pas pensé à un moyen de le faire qui utilise O(nlogu) espace et peut répondre à la requête dans O (1).
Je n'ai aucune idée de comment résoudre ce problème et j'ai l'impression que je ne suis même pas proche de la solution, toute aide serait gentille.
Considérons une structure de données composée de
un tableau A[1,...,u]
de taille u
tel que A[i]=1
si i
est présent dans S, et A[i]=0
sinon. Ce tableau peut être construit à partir de l'ensemble S
dans O (n).
un tableau B[1,...,u]
de taille u
qui stocke la somme cumulée de A
c'est-à-dire B[i] = A[1]+...+A[i]
. Ce tableau peut être construit en O(u) à partir de A
en utilisant la relation B[i] = B[i-1] + A[i]
Pour tous i>1
.
une fonction empty(i,j)
qui renvoie la requête booléenne souhaitée. Si i==1
, Définissez count = B[j]
, Sinon prenez count = B[j]-B[i-1]
. Notez que count
donne le nombre d'éléments distincts dans S compris entre [i,j]
. Une fois que nous avons count
, il suffit de retourner count==0
. Clairement, chaque requête prend O (1).
Edit: Comme indiqué dans les commentaires, la taille de cette structure de données est O (u), ce qui ne correspond pas aux contraintes. Mais j'espère que cela donnera aux autres une cible approximative pour tirer.
Ce n'est pas une solution, mais impossible de l'écrire dans un commentaire. Il y a une idée de la façon de résoudre la tâche plus spécifique qui peut éventuellement aider à résoudre la tâche générique de la question.
La tâche spécifique est la même sauf le point suivant, u = 1024. De plus, ce n'est pas une solution finale, c'est un croquis (pour la tâche spécifique).
Création de structure de données:
Les images du pseudocode suivant utilisent 8 bits sauf 32, juste pour plus de simplicité.
Empty(i, j) {
I = i / 32
J = j / 32
if I != J {
if P == 0: return true
if P(I) == 0: return true
if P(J) == 0: return true
} else {
if P(J=I) == 0: return true
}
return false
}