QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#76216 | #1980. Rule 110 | 123456 | AC ✓ | 238ms | 70368kb | C++23 | 4.4kb | 2023-02-08 14:36:22 | 2023-02-08 14:36:23 |
Judging History
answer
// In the name of God.
// You are anything and We're nothing
// Ya ali!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Node {
int id;
Node* l;
Node* r;
ll cnt;
uint8_t h;
unordered_map<uint8_t, Node*> jump_cache;
Node* replace_left(uint8_t depth, Node* replace);
Node* replace_right(uint8_t depth, Node* replace);
Node* get_left(uint8_t depth);
Node* get_right(uint8_t depth);
Node* jump(uint8_t j);
string print();
};
struct PairHasher {
ll operator()(const pair<int, int> &p) const {
return (ll) p.first << 32 | p.second;
}
};
//map<pair<int, int>, Node*> cache;
unordered_map<pair<int, int>, Node*, PairHasher> cache;
Node* get_node(Node* l, Node* r) {
auto[it, inserted] = cache.insert({{l->id, r->id}, nullptr});
if (!inserted)
return it->second;
// if (!(cache.size() & (cache.size() - 1)))
// cerr << cache.size() << '\n';
// static int created_2 = 0;
// if (l->h == 2) {
// cerr << created_2 << " # " << l->print()+r->print() << '\n';
// ++created_2;
// }
assert(l->h == r->h);
return it->second = new Node{cache.size() - 1, l, r, l->cnt + r->cnt, l->h + 1};
}
Node* base_nodes[2];
Node* get_node(uint8_t h, uint16_t mask) {
if (!h)
return base_nodes[mask];
int w = 1 << h - 1;
return get_node(get_node(h - 1, mask >> w), get_node(h - 1, mask & (1 << w) - 1));
}
Node* get_zero_node(uint8_t h) {
if (!h)
return base_nodes[0];
Node* pre = get_zero_node(h - 1);
return get_node(pre, pre);
}
Node* Node::replace_left(uint8_t depth, Node* replace) {
return !depth ? replace : get_node(l->replace_left(depth - 1, replace), r);
}
Node* Node::replace_right(uint8_t depth, Node* replace) {
return !depth ? replace : get_node(l, r->replace_right(depth - 1, replace));
}
Node* Node::get_right(uint8_t depth) {
return !depth ? this : r->get_right(depth - 1);
}
Node* Node::get_left(uint8_t depth) {
return !depth ? this : l->get_left(depth - 1);
}
Node* Node::jump(uint8_t j) {
assert(j <= h - 2);
if (jump_cache.count(j))
return jump_cache[j];
assert(h > 2);
Node* center = get_node(l->r, r->l);
if (j == h - 2) {
center = center->jump(j - 1);
return jump_cache[j] = get_node(get_node(l->jump(j - 1), center)->jump(j - 1),
get_node(center, r->jump(j - 1))->jump(j - 1));
}
center = center->jump(j);
return jump_cache[j] = get_node(get_node(l->jump(j)->r, center->l), get_node(center->r, r->jump(j)->l));
}
string Node::print() {
if (!h)
return to_string(cnt);
return l->print() + r->print();
}
int next(int mask) {
int ans = 0;
for (int i = 1; i < 3; ++i) {
int cur = (mask >> i + 1 & 1) * 4 + (mask >> i & 1) * 2 + (mask >> i - 1 & 1);
ans |= (cur == 1 || cur == 2 || cur == 3 || cur == 5 || cur == 6) << i;
}
return ans >> 1;
}
void init() {
for (int i = 0; i < 2; ++i)
base_nodes[i] = new Node{i, nullptr, nullptr, i, 0};
cache[{-1, 0}] = nullptr;
cache[{-1, 1}] = nullptr;
for (int mask = 0; mask < 16; ++mask) {
get_node(2, mask)->jump_cache[0] = get_node(1, next(mask));
// cerr << get_node(2, mask)->print() << '\n';
// cerr << get_node(2, mask)->jump(0)->print() << '\n' << '\n';
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
init();
// return 0;
Node* node;
{
string s;
cin >> s;
bitset<16> b(string(s.begin(), s.end()));
node = get_node(4, b.to_ulong());
}
ll k;
cin >> k;
for (int step = 0; step < 60; ++step)
if (k >> step & 1) {
do {
node = get_node(get_node(get_zero_node(node->h - 1), node->l),
get_node(node->r, get_zero_node(node->h - 1)));
node = get_node(get_node(get_zero_node(node->h - 1), node->l),
get_node(node->r, get_zero_node(node->h - 1)));
} while (node->h - 3 <= step);
// cerr << node->print() << '\n';
node = node->jump(step);
// cerr << node->print() << '\n';
}
// cerr << node->print() << '\n';
cout << node->cnt << '\n';
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3312kb
input:
0000000000000000 1
output:
0
result:
ok single line: '0'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3376kb
input:
1111111111111111 1
output:
3
result:
ok single line: '3'
Test #3:
score: 0
Accepted
time: 1ms
memory: 3584kb
input:
0111110110101000 100
output:
64
result:
ok single line: '64'
Test #4:
score: 0
Accepted
time: 3ms
memory: 3980kb
input:
0100011101011100 1000
output:
595
result:
ok single line: '595'
Test #5:
score: 0
Accepted
time: 12ms
memory: 8976kb
input:
0101111110101101 1000000
output:
591156
result:
ok single line: '591156'
Test #6:
score: 0
Accepted
time: 4ms
memory: 4492kb
input:
0011100001111110 1000000000
output:
582589283
result:
ok single line: '582589283'
Test #7:
score: 0
Accepted
time: 27ms
memory: 19512kb
input:
1010100010111101 1152921504606846975
output:
682111393702695301
result:
ok single line: '682111393702695301'
Test #8:
score: 0
Accepted
time: 238ms
memory: 70368kb
input:
1111111010101000 1152921504606846975
output:
681294455007712610
result:
ok single line: '681294455007712610'
Test #9:
score: 0
Accepted
time: 132ms
memory: 43840kb
input:
0010111001010100 1000000000000
output:
590928742595
result:
ok single line: '590928742595'
Test #10:
score: 0
Accepted
time: 2ms
memory: 3472kb
input:
0010000001010100 0
output:
4
result:
ok single line: '4'