import java.io.*; import java.util.*; import java.awt.geom.*; /** * Solution to Tourists * * @author vanb */ public class tourists_vanb { public Scanner sc; public PrintStream ps; /** A list of the Attractions, indexed by their node number */ public Attraction attractions[]; /** A list of Attractions, indexed by their Euler path visit number. */ public Attraction euler[]; /** Position in the Euler path */ public int count = 0; /** Segment Tree */ public Attraction segtree[]; /** * Capture information about an Attraction, which will be a node in a tree. * * @author vanb */ public class Attraction { /** Visitation number in Euler path in & out, and depth. */ public int in, out, depth; /** Adjacent Attractions */ public LinkedList neighbors = new LinkedList(); /** * Build the parameters of a node, * specifically Euler path in & out numbers, and depth. * * @param depth Depth of this node * @param from The node we came from */ public void build( int depth, Attraction from ) { // Record depth, and increment depth for neighbors. this.depth = depth++; // Record this node's IN position in the Euler path // If this node has no neighbors, then it's also the OUT position euler[this.in = this.out = ++count] = this; // Visit neighbors, skipping the node we came from. for( Attraction neighbor : neighbors ) if( neighbor!=from ) { //Visit neighbor neighbor.build( depth, this ); // Put this node in the Euler path again // Remember this node's OUT position in the Euler path // (last one wins) euler[this.out = ++count] = this; } } } /** * Build the Segment Tree subtree rooted at a node. * * @param node Root node of subtree * @param lo Lower bound of segment * @param hi Upper bound of segment * @return */ public Attraction buildSegmentTree( int node, int lo, int hi ) { if( lo==hi ) { // If lo=hi, then we're at a leaf. segtree[node] = euler[lo]; } else { // Build left and right subtrees int mid = (hi+lo)/2; Attraction left = buildSegmentTree( node+node, lo, mid ); Attraction right = buildSegmentTree( node+node+1, mid+1, hi ); // Pick the smaller of the two for this node segtree[node] = (left.depth=lower) ? retrieve( node+node, lo, mid, lower, upper ) : null; Attraction right = (midx and y%x==0 for( int x=1; x<=n; x++ ) for( int y=x+x; y<=n; y+=x ) { // 'first' will be the node which comes earlier in the Euler path. // 'last' will (obviously) be the one that comes later in the Euler path. Attraction first, last; if( attractions[x].in last.out ) { // In an Euler path, a node is an ancestor of // another node iff ancestor.indescendant.out. // That is, you hit the ancestor on the way into the subtree, // then you hit the descendant, then you hit the ancestor again on the way out. // We already know that first.inlast.out, // then last must be a direct descendant of first. // So the distance is the different in their depths, plus one for // first itself. total += last.depth - first.depth + 1; } else { // The lower bound of our interval in the Euler path is first.out, // and the upper bound is last.in. Attraction ancestor = retrieve( 1, 1, count, first.out, last.in ); // The path from first to last goes from first, up to ancestor, and then down to last. // For the total, we need the distance from first to ancestor (first.depth-ancestor.depth), // plus the distance from ancestor to last (last.depth-ancestor.depth), // plus one for the ancestor itself total += first.depth-ancestor.depth + last.depth-ancestor.depth + 1; } } ps.println( total ); } /** * @param args */ public static void main( String[] args ) throws Exception { new tourists_vanb().doit(); } }