挑战程序竞赛系列(73):4.7高度数组(3)
来源:互联网 发布:linux装java环境 编辑:程序博客网 时间:2024/06/09 22:15
挑战程序竞赛系列(73):4.7高度数组(3)
传送门:POJ 3729: Facer’s String
题意:
公共子串:
给出两个字符串A,B,求满足下列条件的C的个数:
1. C是A的子串
2. C也是B的子串
3. C加上其在A中的后继字符(若在最尾则加上空格字符)不能够在B中出现
其实就是问A中有多少个长度为K的子串在B中刚好存在,且再加上后一个字符形成的子串在B中不存在.
思路:
求出A中存在多少后缀,使得其和B的前缀长度大于等于k,再求出A中存在多少后缀,使得其和B的前缀长度等于k+1,最后两式相减。
所以在>=k的范围内,存在一个B,就可以统计A的后缀个数了,若没有B,则统计也没用。
代码如下:
import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.util.Arrays;import java.util.Comparator;import java.util.Map;import java.util.StringTokenizer;public class Main{ String INPUT = "./data/judge/201709/P3729.txt"; public static void main(String[] args) throws IOException { new Main().run(); } class SuffixArray { int k = 1; int n; Integer[] sa; int[] rank, tmp; int[] lcp; SuffixArray(int[] arra) { n = arra.length; sa = new Integer[n + 1]; rank = new int[n + 1]; tmp = new int[n + 1]; lcp = new int[n]; for (int i = 0; i <= n; ++i) { sa[i] = i; rank[i] = i < n ? arra[i] : -1; } for (k = 1; k <= n; k <<= 1) { Arrays.sort(sa, cmp); tmp[sa[0]] = 0; for (int i = 1; i <= n; ++i) { tmp[sa[i]] = tmp[sa[i - 1]] + (cmp.compare(sa[i - 1], sa[i]) < 0 ? 1 : 0); } for (int i = 0; i <= n; ++i) { rank[i] = tmp[i]; } } // lcp int h = 0; for (int i = 0; i <= n; ++i) rank[sa[i]] = i; for (int i = 0; i < n; ++i) { int j = sa[rank[i] - 1]; if (h > 0) h--; for (; i + h < n && j + h < n; ++h) { if (arra[i + h] != arra[j + h]) break; } lcp[rank[i] - 1] = h; } } Comparator<Integer> cmp = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { int i = o1; int j = o2; if (rank[i] != rank[j]) return rank[i] - rank[j]; else { int ri = i + k <= n ? rank[i + k] : -1; int rj = j + k <= n ? rank[j + k] : -1; return ri - rj; } } }; } void read() { while (more()) { int m = ni(); int n = ni(); int k = ni(); int[] arra = new int[m + n + 1]; for (int i = 0; i < m; ++i) { arra[i] = ni(); arra[i] ++; } arra[m] = 10000 + 8; for (int i = 0; i < n; ++i) { arra[i + m + 1] = ni(); arra[i + m + 1] ++; } SuffixArray sa = new SuffixArray(arra); out.println(solve(k, m, sa) - solve(k + 1, m, sa)); } } int solve(int k, int m, SuffixArray sa) { int ans = 0, A = 0, B = 0; for (int i = 0; i < sa.n; i++) {// 统计lcp[i]>=k的连续区间内的A子串 if (sa.lcp[i] < k) { if (B > 0) ans += A; A = 0; B = 0; } if (sa.sa[i + 1] < m) A++; else B++; } return ans; } FastScanner in; PrintWriter out; void run() throws IOException { boolean oj; try { oj = !System.getProperty("user.dir").equals("F:\\java_workspace\\leetcode"); } catch (Exception e) { oj = System.getProperty("ONLINE_JUDGE") != null; } InputStream is = oj ? System.in : new FileInputStream(new File(INPUT)); in = new FastScanner(is); out = new PrintWriter(System.out); long s = System.currentTimeMillis(); read(); out.flush(); if (!oj) { System.out.println("[" + (System.currentTimeMillis() - s) + "ms]"); } } public boolean more() { return in.hasNext(); } public int ni() { return in.nextInt(); } public long nl() { return in.nextLong(); } public double nd() { return in.nextDouble(); } public String ns() { return in.nextString(); } public char nc() { return in.nextChar(); } class FastScanner { BufferedReader br; StringTokenizer st; boolean hasNext; public FastScanner(InputStream is) throws IOException { br = new BufferedReader(new InputStreamReader(is)); hasNext = true; } public String nextToken() { while (st == null || !st.hasMoreTokens()) { try { st = new StringTokenizer(br.readLine()); } catch (Exception e) { hasNext = false; return "##"; } } return st.nextToken(); } String next = null; public boolean hasNext() { next = nextToken(); return hasNext; } public int nextInt() { if (next == null) { hasNext(); } String more = next; next = null; return Integer.parseInt(more); } public long nextLong() { if (next == null) { hasNext(); } String more = next; next = null; return Long.parseLong(more); } public double nextDouble() { if (next == null) { hasNext(); } String more = next; next = null; return Double.parseDouble(more); } public String nextString() { if (next == null) { hasNext(); } String more = next; next = null; return more; } public char nextChar() { if (next == null) { hasNext(); } String more = next; next = null; return more.charAt(0); } } static class ArrayUtils { public static void fill(int[][] f, int value) { for (int i = 0; i < f.length; ++i) { Arrays.fill(f[i], value); } } public static void fill(int[][][] f, int value) { for (int i = 0; i < f.length; ++i) { fill(f[i], value); } } public static void fill(int[][][][] f, int value) { for (int i = 0; i < f.length; ++i) { fill(f[i], value); } } }}
阅读全文
0 0
- 挑战程序竞赛系列(73):4.7高度数组(3)
- 挑战程序竞赛系列(71):4.7高度数组(1)
- 挑战程序竞赛系列(72):4.7高度数组(2)
- 挑战程序竞赛系列(69):4.7后缀数组(1)
- 挑战程序竞赛系列(70):4.7后缀数组(2)
- 挑战程序竞赛系列(65):4.7字符串上的动态规划(3)
- 挑战程序竞赛系列(68):4.7字符串匹配(3)
- 挑战程序竞赛系列(81):4.3 LCA(1)
- 挑战程序竞赛系列(82):4.3 LCA(2)
- 挑战程序竞赛系列(1):2.3动态规划
- 挑战程序竞赛系列(4):2.1深度优先搜索
- 挑战程序竞赛系列(5):2.1广度优先搜索
- 挑战程序竞赛系列(6):2.1穷尽搜索
- 挑战程序竞赛系列(9):2.4优先队列
- 挑战程序竞赛系列(10):2.4并查集
- 挑战程序竞赛系列(11):2.5最短路径
- 挑战程序竞赛系列(12):2.5最小生成树
- 挑战程序竞赛系列(13):2.6辗转相除法
- 小白:html
- 理解这两点,也就理解了paxos协议的精髓
- js基础知识示例3--对多选框操作,输出多选框的个数 fl ch2 p29
- 测试管理--测试的任务安排
- 仿京东项目
- 挑战程序竞赛系列(73):4.7高度数组(3)
- java基础二
- Java当中的数据结构表(ADT)解析(上)
- 数据结构——单链表模板类
- JavaScript内置对象
- 线程读写锁的实现
- 第三周第2次课
- 2017.9.24开学第四周周总结
- 【Java】の基础——几种线程同步方式