#include #include #include using namespace std; map > GRAPH; map VALUE; map PREV_VALUE; set VISITED; int NODE_INDEX = 0; void Clear() { GRAPH.clear(); VALUE.clear(); PREV_VALUE.clear(); VISITED.clear(); NODE_INDEX = 0; } void DeleteTree(int index) { if (VISITED.find(index) != VISITED.end()){ return; } map >::iterator it = GRAPH.find(index); for (set::iterator itn = it->second.begin(); itn != it->second.end(); ++itn){ DeleteTree(*itn); if (GRAPH.find(*itn) != GRAPH.end()){ GRAPH[*itn].erase(index); } } GRAPH.erase(index); VALUE.erase(index); PREV_VALUE.erase(index); } void DeleteOneNode(int index) { const set& s = GRAPH[index]; if (s.size() > 2 || s.size() == 0){ cout << "Error : DeleteOneNode node:" << s.size() << endl; return; } if (s.size() == 1){ GRAPH[*s.begin()].erase(index); GRAPH.erase(index); VALUE.erase(index); PREV_VALUE.erase(index); return; } set::const_iterator it = s.begin(); int first = *it++; int second = *it; GRAPH[first].insert(second); GRAPH[second].insert(first); GRAPH.erase(index); VALUE.erase(index); PREV_VALUE.erase(index); } void AddNode(int index, int number) { int new_index = NODE_INDEX++; GRAPH[new_index].insert(index); GRAPH[index].insert(new_index); VALUE[new_index] = number; PREV_VALUE[new_index] = number; } int GetNext(int number) { number = number * 3 + 1; while (number % 2 == 0){ number /= 2; } return number; } int GetLeaderBonus(int number) { number = (number + 1) / 2; if (number % 2 == 0){ --number; } return number; } int GetLeafBonus(int number) { number = (number + 1) / 2; if (number % 2 == 0){ ++number; } return number; } int FindNextLeader() { int index = -1; int max_number = -1; int count = -1; for (map::iterator it = VALUE.begin(); it != VALUE.end(); ++it){ if (max_number < it->second){ max_number = it->second; count = 1; index = it->first; } else if (max_number == it->second){ ++count; } } if (count != 1){ return -1; } return index; } void DFSNumber(int index) { if (VISITED.find(index) != VISITED.end()){ return; } VISITED.insert(index); const set& s = GRAPH[index]; int &number = VALUE[index]; PREV_VALUE[index] = number; number = GetNext(number); for (set::const_iterator it = s.begin(); it != s.end(); ++it){ DFSNumber(*it); } VISITED.erase(index); } void DFSReconstruct(int index) { if (VISITED.find(index) != VISITED.end()){ return; } VISITED.insert(index); const set& s = GRAPH[index]; if (VALUE[index] == 1){ if (s.size() == 1){ DeleteOneNode(index); } else if (s.size() == 2){ set::const_iterator it = s.begin(); int first = *it++; int second = *it; if (VISITED.find(first) != VISITED.end()){ swap(first, second); } DFSReconstruct(first); DeleteOneNode(index); } else { DeleteTree(index); } } else { for (set::const_iterator it = s.begin(); it != s.end(); ++it){ DFSReconstruct(*it); } if (s.size() == 1){ if (PREV_VALUE[index] < VALUE[index]){ AddNode(index, GetLeafBonus(VALUE[index])); } } } VISITED.erase(index); } int LEADER = -1; void Update() { VISITED.clear(); DFSNumber(LEADER); VISITED.clear(); DFSReconstruct(LEADER); AddNode(LEADER, GetLeafBonus(VALUE[LEADER])); int l = FindNextLeader(); if (l != -1){ LEADER = l; } if (GRAPH.empty()){ LEADER = -1; } } main() { int n; while (cin >> n && n){ Clear(); GRAPH[0]; VALUE[0] = n; PREV_VALUE[0] = n; LEADER = FindNextLeader(); cerr << LEADER << " "; int answer = 0; int max_count = 1; while (LEADER != -1){ Update(); ++answer; max_count = max((int)GRAPH.size(), max_count); } cout << answer << " " << max_count << endl; } }