#include <iostream>
#include <memory>
#include <vector>
#include <ctime>
static const uint64_t SEED = 0xDEADBEEFull;
static const size_t ROWS = 10000;
static const size_t COLS = 10000;
static const uint32_t COLORS_NUM = 3;
uint32_t LCGRand()
{
static uint64_t seed = SEED;
seed = seed * 6364136223846793005 + 1442695040888963407;
return seed >> 32;
}
struct Block {
typedef std::shared_ptr<Block> Ptr;
uint32_t color;
size_t size;
Ptr redir;
};
int main()
{
std::vector<Block::Ptr> up_row(COLS);
size_t max_size = 0;
clock_t start = clock();
for (size_t row = 0; row < ROWS; row++) {
Block::Ptr left;
for (size_t col = 0; col < COLS; col++) {
uint32_t color = LCGRand() % COLORS_NUM;
Block::Ptr &up = up_row[col];
while (up && up->redir)
up = up->redir;
Block::Ptr cur;
if (left && (left->color == color)) {
cur = left;
if (up && (up->color == color) && (up != left)) {
left->size += up->size;
up->redir = left;
}
} else if (up && (up->color == color)) {
cur = up;
} else {
cur = std::make_shared<Block>(Block{ color, 0, nullptr });
}
max_size = std::max(max_size, ++cur->size);
left = up = cur;
}
}
std::cout << "Max block size: " << max_size << std::endl
<< "Time: " << (clock() - start) / (CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8Y3RpbWU+CgpzdGF0aWMgY29uc3QgdWludDY0X3QgU0VFRCA9IDB4REVBREJFRUZ1bGw7CnN0YXRpYyBjb25zdCBzaXplX3QgUk9XUyA9IDEwMDAwOwpzdGF0aWMgY29uc3Qgc2l6ZV90IENPTFMgPSAxMDAwMDsKc3RhdGljIGNvbnN0IHVpbnQzMl90IENPTE9SU19OVU0gPSAzOwoKdWludDMyX3QgTENHUmFuZCgpCnsKICAgIHN0YXRpYyB1aW50NjRfdCBzZWVkID0gU0VFRDsKICAgIHNlZWQgPSBzZWVkICogNjM2NDEzNjIyMzg0Njc5MzAwNSArIDE0NDI2OTUwNDA4ODg5NjM0MDc7CiAgICByZXR1cm4gc2VlZCA+PiAzMjsKfQoKc3RydWN0IEJsb2NrIHsKICAgIHR5cGVkZWYgc3RkOjpzaGFyZWRfcHRyPEJsb2NrPiBQdHI7CgogICAgdWludDMyX3QgY29sb3I7CiAgICBzaXplX3Qgc2l6ZTsKICAgIFB0ciByZWRpcjsKfTsKCmludCBtYWluKCkKewogICAgc3RkOjp2ZWN0b3I8QmxvY2s6OlB0cj4gdXBfcm93KENPTFMpOwogICAgc2l6ZV90IG1heF9zaXplID0gMDsKCiAgICBjbG9ja190IHN0YXJ0ID0gY2xvY2soKTsKICAgIGZvciAoc2l6ZV90IHJvdyA9IDA7IHJvdyA8IFJPV1M7IHJvdysrKSB7CiAgICAgICAgQmxvY2s6OlB0ciBsZWZ0OwoKICAgICAgICBmb3IgKHNpemVfdCBjb2wgPSAwOyBjb2wgPCBDT0xTOyBjb2wrKykgewogICAgICAgICAgICB1aW50MzJfdCBjb2xvciA9IExDR1JhbmQoKSAlIENPTE9SU19OVU07CgogICAgICAgICAgICBCbG9jazo6UHRyICZ1cCA9IHVwX3Jvd1tjb2xdOwogICAgICAgICAgICB3aGlsZSAodXAgJiYgdXAtPnJlZGlyKQogICAgICAgICAgICAgICAgdXAgPSB1cC0+cmVkaXI7CgogICAgICAgICAgICBCbG9jazo6UHRyIGN1cjsKICAgICAgICAgICAgaWYgKGxlZnQgJiYgKGxlZnQtPmNvbG9yID09IGNvbG9yKSkgewogICAgICAgICAgICAgICAgY3VyID0gbGVmdDsKCiAgICAgICAgICAgICAgICBpZiAodXAgJiYgKHVwLT5jb2xvciA9PSBjb2xvcikgJiYgKHVwICE9IGxlZnQpKSB7CiAgICAgICAgICAgICAgICAgICAgbGVmdC0+c2l6ZSArPSB1cC0+c2l6ZTsKICAgICAgICAgICAgICAgICAgICB1cC0+cmVkaXIgPSBsZWZ0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHVwICYmICh1cC0+Y29sb3IgPT0gY29sb3IpKSB7CiAgICAgICAgICAgICAgICBjdXIgPSB1cDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGN1ciA9IHN0ZDo6bWFrZV9zaGFyZWQ8QmxvY2s+KEJsb2NreyBjb2xvciwgMCwgbnVsbHB0ciB9KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbWF4X3NpemUgPSBzdGQ6Om1heChtYXhfc2l6ZSwgKytjdXItPnNpemUpOwogICAgICAgICAgICBsZWZ0ID0gdXAgPSBjdXI7CiAgICAgICAgfQogICAgfQoKICAgIHN0ZDo6Y291dCA8PCAiTWF4IGJsb2NrIHNpemU6ICIgPDwgbWF4X3NpemUgPDwgc3RkOjplbmRsCiAgICAgICAgPDwgIlRpbWU6ICIgPDwgKGNsb2NrKCkgLSBzdGFydCkgLyAoQ0xPQ0tTX1BFUl9TRUMgLyAxMDAwKSA8PCAiIG1zIiA8PCBzdGQ6OmVuZGw7CiAgICByZXR1cm4gMDsKfQo=