Advertisement
Guest User

Untitled

a guest
Jun 26th, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.35 KB | None | 0 0
  1. import java.util.*;
  2. import java.io.*;
  3.  
  4. public class Main {
  5.     static class Node {
  6.         String name;
  7.         Node left;
  8.         Node right;
  9.         int childrenCount;
  10.         long subtreeHash;
  11.        
  12.         public Node(String name) {
  13.             this.name = name;
  14.         }
  15.     }
  16.     long X = 99991;
  17.    
  18.     static class Tokenizer {
  19.         String string;
  20.         int at;
  21.        
  22.         public Tokenizer(String string) {
  23.             this.string = string;
  24.             this.at = 0;
  25.         }
  26.        
  27.         public boolean hasNext() {
  28.             return at < string.length();
  29.         }
  30.        
  31.         public char peek() {
  32.             return string.charAt(at);
  33.         }
  34.        
  35.         public char poll() {
  36.             return string.charAt(at++);
  37.         }
  38.  
  39.         public String readName() {
  40.             String result = "";
  41.             while (hasNext() && Character.isLetter(peek())) {
  42.                 result += poll();
  43.             }
  44.             return result;
  45.         }
  46.     }
  47.    
  48.     private void solution() throws IOException {
  49.         int ts = in.nextInt();
  50.         while (ts-- > 0) {
  51.             Tokenizer tokenizer = new Tokenizer(in.nextLine());
  52.             Node head = readTree(tokenizer);
  53.             precalc(head);
  54.             StringBuilder result = new StringBuilder();
  55.             Map<Long, Integer> cache = new HashMap<Long, Integer>();
  56.             this.it = 1;
  57.             solve(head, result, cache);
  58.             out.println(result);
  59.         }
  60.     }
  61.     int it;
  62.  
  63.     private void solve(Node head, StringBuilder result, Map<Long, Integer> cache) {
  64.         if (cache.containsKey(head.subtreeHash)) {
  65.             result.append(cache.get(head.subtreeHash));
  66.         } else {
  67.             cache.put(head.subtreeHash, it++);
  68.             result.append(head.name);
  69.             if (head.left != null) {
  70.                 result.append('(');
  71.                 solve(head.left, result, cache);
  72.                 result.append(',');
  73.                 solve(head.right, result, cache);
  74.                 result.append(')');
  75.             }
  76.         }
  77.        
  78.     }
  79.  
  80.     private void precalc(Node head) {
  81.         if (head != null) {
  82.             precalc(head.left);
  83.             precalc(head.right);
  84.             head.childrenCount = 1 + count(head.left) + count(head.right);
  85.             head.subtreeHash = addToHash(0, head.name);
  86.             if (head.left != null) {
  87.                 head.subtreeHash = addToHash(head.subtreeHash, "(");
  88.                 head.subtreeHash = addToHash(head.subtreeHash, head.left.subtreeHash, 10 * head.left.childrenCount);
  89.                 head.subtreeHash = addToHash(head.subtreeHash, ",");
  90.                 head.subtreeHash = addToHash(head.subtreeHash, head.right.subtreeHash, 10 * head.right.childrenCount);
  91.                 head.subtreeHash = addToHash(head.subtreeHash, ")");
  92.             }
  93.         }
  94.     }
  95.  
  96.     private long addToHash(long hash, long otherHash, int length) {
  97.         return hash * pow(X, length) + otherHash;
  98.     }
  99.  
  100.     private long pow(long a, int k) {
  101.         long res = 1;
  102.         while (k > 0) {
  103.             if ((k & 1) != 0) {
  104.                 res = res * a;
  105.             }
  106.             k >>= 1;
  107.             a = a * a;
  108.         }
  109.         return res;
  110.     }
  111.  
  112.     private long addToHash(long hash, String string) {
  113.         for (char c : string.toCharArray()) {
  114.             hash = hash * X + c;
  115.         }
  116.         return hash;
  117.     }
  118.  
  119.     private int count(Node head) {
  120.         if (head == null) {
  121.             return 0;
  122.         } else {
  123.             return head.childrenCount;
  124.         }
  125.     }
  126.  
  127.     private Node readTree(Tokenizer tokenizer) {
  128.         if (!tokenizer.hasNext()) {
  129.             return null;
  130.         } else {
  131.             Node head = new Node(tokenizer.readName());
  132.             if (tokenizer.hasNext() && tokenizer.peek() == '(') {
  133.                 tokenizer.poll();
  134.                 head.left = readTree(tokenizer);
  135.                 tokenizer.poll();
  136.                 head.right = readTree(tokenizer);
  137.                 tokenizer.poll();
  138.             }
  139.             return head;
  140.         }
  141.     }
  142.  
  143.     public void run() {
  144.         try {
  145.             solution();
  146.             in.reader.close();
  147.             out.close();
  148.         } catch (IOException e) {
  149.             e.printStackTrace();
  150.             System.exit(1);
  151.         }
  152.     }
  153.    
  154.     private class Scanner {
  155.         StringTokenizer tokenizer;
  156.         BufferedReader reader;
  157.        
  158.         public Scanner(Reader reader) {
  159.             this.reader = new BufferedReader(reader);
  160.             this.tokenizer = new StringTokenizer("");
  161.         }
  162.        
  163.         public String nextLine() throws IOException {
  164.             tokenizer = new StringTokenizer("");
  165.             return reader.readLine();
  166.         }
  167.  
  168.         public boolean hasNext() throws IOException {
  169.             while (!tokenizer.hasMoreTokens()) {
  170.                 String line = reader.readLine();
  171.                 if (line == null) {
  172.                     return false;
  173.                 }
  174.                 tokenizer = new StringTokenizer(line);
  175.             }
  176.             return true;
  177.         }
  178.        
  179.         public String next() throws IOException {
  180.             hasNext();
  181.             return tokenizer.nextToken();
  182.         }
  183.        
  184.         public int nextInt() throws IOException {
  185.             return Integer.parseInt(next());
  186.         }
  187.     }
  188.    
  189.     public static void main(String[] args) {
  190.         new Main().run();
  191.     }
  192.    
  193.     Scanner in = new Scanner(new InputStreamReader(System.in));
  194.     PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement