18#include <initializer_list>
41 void QuickSort(
int start,
int end);
44 void Insertion(
int start,
int end);
47 void Exch(
int i,
int j) { Item a = v[i]; v[i] = v[j]; v[j] = a; }
50 void QuickSortIdx(
int start,
int end);
53 void ExchIdx(
int i,
int j) {
int a = (*idx)[i]; (*idx)[i] = (*idx)[j]; (*idx)[j] = a; }
56 static inline int Min(
int a,
int b)
noexcept {
return (a < b) ? a : b; }
59 static inline int Max(
int a,
int b)
noexcept {
return (a > b) ? a : b; }
103 Count(
static_cast<int>(init.size()));
105 for (
const auto& val : init)
156 int oldCount =
Count();
157 Count(oldCount +
static_cast<int>(init.size()));
159 for (
const auto& val : init)
160 v[oldCount + i++] = val;
221 const Item*
Data()
const {
return v; }
233 virtual bool Empty()
const {
return (count == 0); }
286 int Find(Item& i,
bool binary =
false,
int left = 0,
int right = -1);
319 Item*
begin() noexcept {
return v; }
320 Item*
end() noexcept {
return v + count; }
321 const Item*
begin() const noexcept {
return v; }
322 const Item*
end() const noexcept {
return v + count; }
380 Item* aux =
new Item[size];
382 int limite = (count < size ? count : size);
383 for (
int k = limite - 1; k >= 0; --k)
404 : idx(nullptr), v(nullptr), sz(0), count(0)
428 for (
int k = 0; k < size; ++k)
429 operator[](k) = init[k];
467 for (
int i = 0; i < o.count; ++i) {
481 : v(o.v), sz(o.sz), count(o.count)
519 int oldCount = count;
521 Count(oldCount + o.count);
523 for (
int k = 0; k < o.count; ++k) {
524 v[oldCount + k] = o.v[k];
557 if (i < 0 || i >= count)
579 if (right < 0 || right > count - 1) right = count - 1;
580 if (left < 0 || left > right) left = 0;
581 while (left <= right) {
582 int mid = (left + right) >> 1;
583 if (v[mid] == i)
return mid;
584 if (v[mid] < i) left = mid + 1;
585 else right = mid - 1;
589 for (
int k = 0; k < count; ++k)
608 if (idxvect ==
nullptr) {
609 QuickSort(0, count - 1);
610 Insertion(0, count - 1);
615 for (
int k = 0; k < count; ++k)
617 QuickSortIdx(0, count - 1);
631 if (end > count - 1 || end < 0) end = count - 1;
632 if (start < 0) start = 0;
634 QuickSort(start, end);
635 Insertion(start, end);
649 if (end - start > 32) {
651 Exch((start + end) >> 1, end - 1);
652 if (v[end - 1] < v[start]) Exch(end - 1, start);
653 if (v[end] < v[start]) Exch(end, start);
654 if (v[end] < v[end - 1]) Exch(end, end - 1);
659 int i = start - 1, j = end;
662 while (v[++i] < pivot);
663 while (pivot < v[--j] && j > start);
669 QuickSort(start - 1, i - 1);
670 QuickSort(i + 1, end + 1);
683 for (
int i = end; i > start; --i)
687 for (
int i = start + 2; i <= end; ++i) {
690 while (tmp < v[j - 1]) {
708 if (end - start < 3) {
710 if (end - start == 1) {
711 if (v[(*idx)[end]] < v[(*idx)[start]])
714 else if (end - start == 2) {
715 if (v[(*idx)[end - 1]] < v[(*idx)[start]])
716 ExchIdx(end - 1, start);
717 if (v[(*idx)[end]] < v[(*idx)[start]])
719 if (v[(*idx)[end]] < v[(*idx)[end - 1]])
720 ExchIdx(end, end - 1);
725 ExchIdx((start + end) >> 1, end - 1);
726 if (v[(*idx)[end - 1]] < v[(*idx)[start]])
727 ExchIdx(end - 1, start);
728 if (v[(*idx)[end]] < v[(*idx)[start]])
730 if (v[(*idx)[end]] < v[(*idx)[end - 1]])
731 ExchIdx(end, end - 1);
736 int i = start - 1, j = end;
737 Item pivot = v[(*idx)[end]];
739 while (v[(*idx)[++i]] < pivot);
740 while (pivot < v[(*idx)[--j]] && j > start);
746 if (i > start) QuickSortIdx(start - 1, i - 1);
747 if (i < end) QuickSortIdx(i + 1, end + 1);
763 for (
int k = count - 1; k > 0; --k)
777 for (
int w = 0; w < count; ++w) {
795 for (
int j = 0; j < count; ++j) {
811 for (
int k = 0; k < count; ++k) {
828 for (
int k = i; k < count - 1; ++k) {
870 int k = 0, w = 0, s = Count();
871 while (k < other.
Count()) {
872 while (w < s &&
operator[](w) < other[k]) {
875 if (w >= s ||
operator[](w) > other[k]) {
895 int k = 0, w = 0, z = 0;
896 while (k < other.
Count() && w < Count()) {
897 if (
operator[](w) < other[k]) {
900 else if (
operator[](w) == other[k]) {
921 int k = 0, w = 0, z = 0;
922 while (k < other.
Count() && w < Count()) {
923 if (v[w] < other[k]) {
926 else if (v[w] == other[k]) {
933 while (w < Count()) {
948 if (count != other.
Count())
return false;
949 for (
int k = 0; k < count; ++k) {
950 if (v[k] != other[k])
return false;
964 if (count > other.
Count())
return false;
966 for (
int k = 0; k < count; ++k) {
967 while (k2 < other.
Count() && v[k2] < v[k]) {
970 if (k2 >= other.
Count() || other[k2] != v[k]) {
987 if (index < 0) index = Count();
990 int oldCount = Count();
992 if (index > oldCount) index = oldCount;
993 for (
int k = oldCount - 1; k >= index; --k) {
996 for (
int k = 0; k < w; ++k) {
997 v[index + k] = src[k];
1009template <
class Item>
1012 if (index < 0) index = Count();
1013 int oldCount = Count();
1014 Count(oldCount + 1);
1015 if (index > oldCount) index = oldCount;
1016 for (
int k = oldCount - 1; k >= index; --k) {
1027template <
class Item>
1030 for (
int k = 0; k < count / 2; ++k) {
1031 Exch(k, count - 1 - k);
1047template <
class Item>
1051 int n1 = Count(), n2 = other.
Count();
1054 result = abs(n1 - n2);
1055 int m = Min(n1, n2);
1056 for (
int i = 0; i < m; ++i) {
1057 if (v[i] != other[i]) ++result;
1060 else if (type == 1) {
1061 int m = Min(n1, n2);
1062 for (
int i = 0; i < m; ++i) {
1063 result += abs(v[i] - other[i]);
1066 else if (type == 2) {
1067 result = Max(n1, n2);
1068 for (
int i = 0; i + 1 < n1; ++i) {
1069 int j = other.
Find(v[i]);
1070 if (j >= 0 && j + 1 < n2 && v[i + 1] == other[j + 1]) {
1075 else if (type == 3) {
1076 int rows = n1 + 1, cols = n2 + 1;
1079 for (
int i = 0; i < rows; ++i) mtx[i] = i;
1080 for (
int j = 1; j < cols; ++j) mtx[j * rows] = j;
1082 for (
int i = 1; i < rows; ++i) {
1083 for (
int j = 1; j < cols; ++j) {
1084 int cost = (v[i - 1] == other[j - 1] ? 0 : 1);
1085 int val = mtx[(i - 1) + rows * (j - 1)] + cost;
1086 val = Min(val, mtx[(i - 1) + rows * j] + 1);
1087 val = Min(val, mtx[i + rows * (j - 1)] + 1);
1088 mtx[i + rows * j] = val;
1091 result = mtx[n1 + rows * n2];
1102 static FILE* fopen_compat(
const char* filename,
const char* mode) {
1105 fopen_s(&f, filename, mode);
1108 return std::fopen(filename, mode);
1127 int n = (int)strlen(s);
1129 memcpy(
Data(), s, n + 1);
1139 operator const char* ()
const noexcept {
1153 va_start(args, fmt);
1154 int needed = vsnprintf(
nullptr, 0, fmt, args);
1168 va_start(args, fmt);
1169 vsnprintf(
Data() + old, needed + 1, fmt, args);
1189 unsigned int hash = 5381;
1190 for (
unsigned char c : *
this)
1191 hash = ((hash << 5) + hash) + c;
1198 const char* s =
Data();
1203 while (i < n && strchr(delim, s[i]))
1206 if (i >= n || s[i] == 0)
1212 while (i < n && s[i] != 0 && !strchr(delim, s[i]))
1216 int len = i - start;
1219 memcpy(
tok.
Data(), s + start, len);
1233 FILE* f = fopen_compat(
Data(),
"r");
1234 if (!f)
return lines;
1235 while ((c = fgetc(f)) != EOF)
1240 else if (c !=
'\r') {
1249 FILE* f = fopen_compat(
Data(), append ?
"ab" :
"wb");
1250 if (!f)
return *
this;
1251 for (
const auto& line : lines)
1252 fprintf(f,
"%s\n", *line);
1265 inline unsigned int Hash()
const;
1278 explicit operator bool()
const {
1279 for (
int i = 0; i <
Count(); i++)
1280 if (
Data()[i] != 0ULL)
1286 inline bool GetBit(
int index)
const;
1287 inline void SetBit(
int index,
bool value);
1290 inline void SetBits(uint64_t value,
int bitIndex,
int bitCount);
1291 inline uint64_t
GetBits(
int bitIndex,
int bitCount)
const;
1296 uint32_t h = 2166136261;
1297 for (uint64_t word : *
this) {
1301 for (
int i = 0; i < 8 && word; i++) {
1302 unsigned char octeto = word & 255;
1314 for (
int i = 0; i < n; i++)
1315 r[i] =
Data()[i] & other[i];
1322 for (
int i = 0; i < n; i++) {
1323 uint64_t a = (i <
Count()) ?
Data()[i] : 0;
1324 uint64_t b = (i < other.
Count()) ? other[i] : 0;
1333 for (
int i = 0; i < n; i++) {
1334 uint64_t a = (i <
Count()) ?
Data()[i] : 0;
1335 uint64_t b = (i < other.
Count()) ? other[i] : 0;
1343 for (
int i = 0; i <
Count(); i++)
1351 if (w >=
Count())
return false;
1352 return (
Data()[w] >> o) & 1ULL;
1356 int w = bitIndex >> 6;
1357 int o = bitIndex & 63;
1359 uint64_t v = (w <
Count()) ? (
Data()[w] >> o) : 0;
1361 if (o + bitCount > 64 && w + 1 <
Count())
1362 v |=
Data()[w + 1] << (64 - o);
1364 return v & (bitCount == 64 ? ~0ULL : ((1ULL << bitCount) - 1));
1372 int currentWords =
Count();
1374 while (currentWords <
Count())
1375 Data()[currentWords++] = 0ULL;
1378 uint64_t& word = (*this)[w];
1380 word |= (1ULL << o);
1382 word &= ~(1ULL << o);
1386 int w = bitIndex >> 6;
1387 int o = bitIndex & 63;
1389 if (w + 1 >=
Count()) {
1390 int currentWords =
Count();
1392 while (currentWords <
Count())
1393 Data()[currentWords++] = 0ULL;
1396 uint64_t mask = (bitCount == 64 ? ~0ULL : ((1ULL << bitCount) - 1)) << o;
1397 Data()[w] = (
Data()[w] & ~mask) | ((value << o) & mask);
1399 if (o + bitCount > 64) {
1400 int spill = (o + bitCount) - 64;
1401 uint64_t mask2 = (1ULL << spill) - 1;
1402 Data()[w + 1] = (
Data()[w + 1] & ~mask2) | (value >> (64 - o));
1410 char* token = buffer.Data();
1412 if (!str || *str ==
'\0')
1416 if ((pt = strchr(token,
','))) {
1421 if ((pt = strchr(token,
',')))
1428 if ((pt = strchr(token,
':'))) {
1431 int A = atoi(token);
1433 if ((pt2 = strchr(pt + 1,
':'))) {
1435 if ((C = atoi(pt2 + 1)) <= 0)
1438 int B = atoi(pt + 1);
1444 for (
int i = A; i <= B; i += C)
1448 *
this += atoi(token);
Interface para geração de números aleatórios independentes do sistema operativo.
TVector< int > _TV(const char *str)
uint64_t GetBits(int bitIndex, int bitCount) const
TBits operator|(const TBits &other) const
void SetBits(uint64_t value, int bitIndex, int bitCount)
TBits operator&(const TBits &other) const
TBits & operator^=(const TBits &other)
void SetBit(int index, bool value)
TBits & operator|=(const TBits &other)
TBits operator^(const TBits &other) const
unsigned int Hash() const
bool GetBit(int index) const
TBits & operator&=(const TBits &other)
TString & operator+=(const TString &other)
TVector< TString > tok(const char *delim=" \t\n\r") const
TString & printf(const char *fmt,...)
const char * operator*() const noexcept
unsigned int Hash() const
TVector< TString > readLines()
TString & writeLines(const TVector< TString > &lines, bool append=false)
friend bool operator!=(const TVector< Item > &a, const TVector< Item > &b)
TVector< Item > & Count(int value)
Ajusta o tamanho lógico do vetor para value.
TVector< Item > & BeASet()
Converte o vetor num conjunto: remove duplicados e ordena.
virtual ~TVector() noexcept
Destrutor.
static Item erro
Valor retornado em casos de acesso inválido.
bool Equal(const TVector< Item > &v) const
Verifica se dois vetores-conjunto são iguais.
friend TVector< Item > operator+(TVector< Item > a, const TVector< Item > &b)
TVector & operator=(TVector &&o) noexcept
Operador de atribuição por movimentação.
TVector< Item > & Replace(Item const &iold, Item const &inew)
Substitui todas as ocorrências de um valor antigo por um novo.
Item & operator[](int i)
Acesso por índice com auto-expansão.
TVector & operator=(const TVector &o)
Operador de atribuição por cópia.
const Item * begin() const noexcept
TVector< Item > & Insert(TVector< Item > &v, int index=0)
Insere um vetor de itens na posição indicada.
TVector< Item > & RandomOrder()
Coloca os elementos em ordem aleatória (Fisher–Yates shuffle).
TVector< Item > & Difference(const TVector< Item > &v)
Diferença deste conjunto em relação a outro.
TVector< Item > & Sort(TVector< int > *idxvect=nullptr)
Ordena todo o vetor, opcionalmente devolvendo índices ordenados.
TVector< Item > & operator+=(const Item &x)
TVector & operator+=(const TVector &o)
Concatena outro vetor a este.
TVector< Item > & operator-=(const Item &x)
friend bool operator==(const TVector< Item > &a, const TVector< Item > &b)
TVector(const char *str)
Constrói um vetor de inteiros a partir de uma string no formato de lista.
TVector< Item > & Remove(Item const &i)
Remove todas as ocorrências de um dado elemento.
TVector & operator+=(std::initializer_list< Item > init)
Adiciona múltiplos elementos ao final do vetor.
int Distance(TVector< Item > &v, int type=0)
Calcula várias métricas de “distância” entre vetores.
TVector< Item > & Intersection(const TVector< Item > &v)
Interseção deste conjunto com outro.
const Item & operator[](int i) const
Acesso constante por índice sem modificação de tamanho.
const Item * Data() const
Acesso direto constante.
bool Contained(const TVector< Item > &v) const
Verifica se este conjunto está contido no outro.
TVector< Item > & Add(Item a)
TVector< Item > & Reset(Item const &i)
Preenche todo o vetor com um mesmo valor.
TVector< Item > & Invert()
Inverte a ordem dos elementos no vetor.
TVector< Item > & Insert(Item a, int index=0)
Insere um único elemento na posição indicada.
void Sort(int start, int end=-1)
Ordena um subintervalo [start,end] do vetor.
TVector< Item > & Delete(int i)
Remove o elemento na posição i deslocando os seguintes.
TVector< Item > & operator+=(const char *str)=delete
Acrescenta elementos a partir de uma string no formato de lista.
Item * Data()
Acesso direto.
virtual bool Empty() const
int Find(Item &i, bool binary=false, int left=0, int right=-1)
Procura um elemento no vetor.
TVector(int size, Item const *init)
Constrói um vetor pré-carregado a partir de um array.
TVector< Item > & Union(const TVector< Item > &v)
Realiza a união deste conjunto com outro.
TVector(int size=0)
Construtor.
const Item * end() const noexcept
TVector< Item > & Push(Item a)
unsigned int rand(int seq)
Retorna o próximo valor pseudo-aleatório.