static NodeRefPtr MakeChain(size_t n) { if (n == 0) return TfNullPtr; else { NodeRefPtr root = Node::New(); root->SetChild(MakeChain(n-1)); return root; } }
int main(){ short i,a,b; int q; char opt; read(N); for(i=1;i<N;++i) read2(a,b),addEdge(V+a,V+b); for(i=1;i<=N;++i) read(V[i].w); V->top=V; V[1].BuildTree(V,1); MakeChain(); scanf("%d\n",&q); while(q--) switch(opt=(getchar(),getchar()),read2(a,b),opt){ case 'H':V[a].Modify(b);break; case 'M':writeln(Max(V+a,V+b));break; case 'S':writeln(Sum(V+a,V+b)); } }
static bool Test_TfRefPtr() { TestConversions(); TestNullptrComparisons(); NodeRefPtr chain1 = MakeChain(10); NodeRefPtr chain2 = MakeChain(5); NodePtr gChain1 = chain1; NodePtr gChain2 = chain2; TF_AXIOM(chain1->GetLength() == 10); TF_AXIOM(chain2->GetLength() == 5); TF_AXIOM(gChain1->GetLength() == 10); TF_AXIOM(gChain2->GetLength() == 5); std::cout << "total nodes (should be 15): " << Node::GetTotalNodeCount() << std::endl; NodeRefPtr start = Node::New(); start->SetChild(chain1); chain1 = TfNullPtr; TF_AXIOM(gChain1->GetLength() == 10); TF_AXIOM(start->GetLength() == 11); std::cout << "total nodes (should be one more than previous): " << Node::GetTotalNodeCount() << std::endl; start->SetChild(gChain2); chain2 = TfNullPtr; TF_AXIOM(start->GetLength() == 6); TF_AXIOM(!gChain1); TF_AXIOM(gChain2); TF_AXIOM(start->GetLength() == start->GetTail()->GetRevLength()); std::cout << "total nodes (should be 10 less than last): " << Node::GetTotalNodeCount() << std::endl; start = TfNullPtr; TF_AXIOM(!gChain1); TF_AXIOM(!gChain2); std::cout << "total nodes (should be zero): " << Node::GetTotalNodeCount() << std::endl; TF_AXIOM(Node::GetTotalNodeCount() == 0); chain1 = MakeChain(5); gChain2 = chain2 = MakeChain(5); chain1->GetTail()->SetChild(chain2); TF_AXIOM(gChain2->GetRevLength() == 6); chain1 = TfNullPtr; TF_AXIOM(gChain2->GetRevLength() == 1); chain2 = TfNullPtr; TF_AXIOM(!gChain2); TF_AXIOM(Node::GetTotalNodeCount() == 0); SuperNodeRefPtr superPtr = SuperNode::New(); NodeRefPtr basePtr = superPtr; NodePtr baseBackPtr = basePtr; TF_AXIOM(TfDynamic_cast<SuperNodeRefPtr>(basePtr) == superPtr); TF_AXIOM(TfSafeDynamic_cast<SuperNodeRefPtr>(basePtr) == superPtr); TF_AXIOM(TfDynamic_cast<SuperNodePtr>(baseBackPtr) == superPtr); TF_AXIOM(TfSafeDynamic_cast<SuperNodePtr>(baseBackPtr) == superPtr); // Test swap { const NodeRefPtr n1 = Node::New(); const NodeRefPtr n2 = Node::New(); NodeRefPtr a = n1; NodeRefPtr b = n2; TF_AXIOM(a); TF_AXIOM(b); TF_AXIOM(a != b); TF_AXIOM(a == n1); TF_AXIOM(b == n2); a.swap(b); TF_AXIOM(a == n2); TF_AXIOM(b == n1); // Test self-swap a.swap(a); TF_AXIOM(a == n2); b.swap(b); TF_AXIOM(b == n1); } // Test move constructor and assignment operators { NodeRefPtr n1 = Node::New(); Node* n1Ptr = get_pointer(n1); TF_AXIOM(n1); NodeRefPtr n2(std::move(n1)); TF_AXIOM(n2); TF_AXIOM(get_pointer(n2) == n1Ptr); TF_AXIOM(!n1); n1 = Node::New(); n1Ptr = get_pointer(n1); TF_AXIOM(n1); n2 = std::move(n1); TF_AXIOM(n2); TF_AXIOM(get_pointer(n2) == n1Ptr); TF_AXIOM(!n1); } // Test move constructor and assignment operators on // convertible pointer types. { SuperNodeRefPtr subNode = SuperNode::New(); SuperNode* subNodePtr = get_pointer(subNode); TF_AXIOM(subNode); NodeRefPtr baseNode(std::move(subNode)); TF_AXIOM(baseNode); TF_AXIOM(get_pointer(baseNode) == subNodePtr); TF_AXIOM(!subNode); subNode = SuperNode::New(); subNodePtr = get_pointer(subNode); TF_AXIOM(subNode); baseNode = std::move(subNode); TF_AXIOM(baseNode); TF_AXIOM(get_pointer(baseNode) == subNodePtr); TF_AXIOM(!subNode); } return true; }