Advertisement
Guest User

Untitled

a guest
Apr 10th, 2020
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.08 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. class Main {
  5.     public static void main(String[] args) throws Exception {
  6.         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  7.         PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out), false);
  8.         new Main(in, out);
  9.         out.close();
  10.     }
  11.  
  12.     BIT[] sz;
  13.     BIT[][] cnt;
  14.     Trie[] trie;
  15.  
  16.     Main(BufferedReader in, PrintWriter out) throws Exception {
  17.         String[] vals = in.readLine().split(" ");
  18.         int n = Integer.parseInt(vals[0]);
  19.         int q = Integer.parseInt(vals[1]);
  20.         String[] words = new String[n+1];
  21.         init(n);
  22.         for (int i = 1; i <= n; ++i) {
  23.             words[i] = in.readLine();
  24.         }
  25.         Query[] queries = new Query[q];
  26.         for (int i = 0; i < q; ++i) {
  27.             vals = in.readLine().split(" ");
  28.             queries[i] = new Query();
  29.             queries[i].i = i;
  30.             queries[i].l = Integer.parseInt(vals[0]);
  31.             queries[i].r = Integer.parseInt(vals[1]);
  32.         }
  33.         Arrays.sort(queries, new Comparator<Query>() {
  34.             @Override
  35.             public int compare(Query q1, Query q2) {
  36.                 return Integer.compare(q1.r, q2.r);
  37.             }
  38.         });
  39.         for (int i = 0, r = 0; i < q; ++i) {
  40.             while (r < queries[i].r) {
  41.                 ++r;
  42.                 add(r, words[r]);
  43.             }
  44.             queries[i].v = solve(queries[i].l, queries[i].r);
  45.         }
  46.         Arrays.sort(queries, new Comparator<Query>() {
  47.             @Override
  48.             public int compare(Query q1, Query q2) {
  49.                 return Integer.compare(q1.i, q2.i);
  50.             }
  51.         });
  52.         for (int i = 0; i < q; ++i) {
  53.             out.println(queries[i].v);
  54.         }
  55.     }
  56.  
  57.     void init(int n) {
  58.         sz = new BIT[2];
  59.         trie = new Trie[2];
  60.         cnt = new BIT[2][26];
  61.         for (int i = 0; i < 2; ++i) {
  62.             sz[i] = new BIT(n);
  63.             trie[i] = new Trie();
  64.             for (int j = 0; j < cnt[i].length; ++j) {
  65.                 cnt[i][j] = new BIT(n);
  66.             }
  67.         }
  68.     }
  69.  
  70.     String reverse(String word) {
  71.         StringBuilder sb = new StringBuilder(word);
  72.         return sb.reverse().toString();
  73.     }
  74.  
  75.     void add(int i, String word) {
  76.         trie[0].add(i, word, sz[0], cnt[0]);
  77.         trie[1].add(i, reverse(word), sz[1], cnt[1]);
  78.     }
  79.  
  80.     long solve(int l, int r) {
  81.         long ans = sz[0].query(l, r) * sz[1].query(l, r);
  82.         for (int i = 0; i < 26; ++i) {
  83.             ans -= cnt[0][i].query(l, r) * cnt[1][i].query(l, r);
  84.         }
  85.         return ans;
  86.     }
  87.  
  88.     class Query {
  89.         int i, l, r;
  90.         long v;
  91.     }
  92.  
  93.     class Trie {
  94.         Trie[] edges;
  95.         int lastIndex;
  96.  
  97.         Trie() {
  98.             edges = new Trie[26];
  99.             lastIndex = -1;
  100.         }
  101.  
  102.         void add(int k, String word, BIT sz, BIT[] cnt) {
  103.             Trie curr = this;
  104.             for (int i = 0; i < word.length(); ++i) {
  105.                 int c = word.charAt(i) - 'a';
  106.                 if (curr.edges[c] == null) {
  107.                     curr.edges[c] = new Trie();
  108.                 } else {
  109.                     int j = curr.edges[c].lastIndex;
  110.                     sz.update(j, -1);
  111.                     if (i > 0) cnt[c].update(j, -1);
  112.                 }
  113.                 sz.update(k, 1);
  114.                 if (i > 0) cnt[c].update(k, 1);
  115.                 curr = curr.edges[c];
  116.                 curr.lastIndex = k;
  117.             }
  118.         }
  119.     }
  120.  
  121.     class BIT {
  122.         int[] arr;
  123.  
  124.         BIT(int size) {
  125.             arr = new int[size+1];
  126.         }
  127.  
  128.         void update(int p, int v) {
  129.             while (p < arr.length) {
  130.                 arr[p] += v;
  131.                 p += (p & -p);
  132.             }
  133.         }
  134.  
  135.         long query(int p) {
  136.             long ans = 0;
  137.             while (p > 0) {
  138.                 ans += arr[p];
  139.                 p -= (p & -p);
  140.             }
  141.             return ans;
  142.         }
  143.  
  144.         long query(int l, int r) {
  145.             return query(r) - query(l-1);
  146.         }
  147.     }
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement