zoukankan      html  css  js  c++  java
  • ACM-ICPC北京赛区(2017)网络赛2【后缀数组+Java//不会】

    #1579 : Reverse Suffix Array

    时间限制:1000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    There is a strong data structure called "Suffix Array" which can effectively solve string problems.

    Let S=s1s2...sn be a string and let S[i,j] denote the substring of S ranging from i to j. The suffix array A of S is now defined to be an array of integers providing the starting positions of suffixes of S in lexicographical order. This means, an entry A[i] is the starting position of the i-th smallest suffix in S and thus for all 1 < i ≤ n:  S[A[i-1], n] < S[A[i], n].

    For example: the suffix array of “banana” is [6, 4, 2, 1, 5, 3].

    Here comes another problem called "Reverse Suffix Array".

    Given a suffix array, you need to figure out how many lower case strings are there whose suffix array is the same as the given suffix array.

    输入

    First line contains a positive number T which means the number of test cases.

    For each test cases, first line contains a positive number N, the second line contains N integer(s) which indicates the suffix array A.

    1 ≤ T ≤ 10, 1 ≤ N ≤ 100,000

    1 ≤ A[i] ≤ N (i = 1...N)

    输出

    For each test case, output one line contains the answer. If no qualified string exists, output 0.

    样例输入
    1
    5
    4 3 2 5 1
    样例输出
    98280
    【题意】:已知后缀数组,求原串的可能情况数。
    【分析】:java,26^3 dp,http://blog.csdn.net/skywalkert/article/details/51731556(在 cdoj 上也有一个类似
    【代码】:
    import java.io.OutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.util.StringTokenizer;
    import java.math.BigInteger;
    import java.io.IOException;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.io.InputStream;
    
    /**
     * Built using CHelper plug-in
     * Actual solution is at the top
     */
    public class Main {
        public static void main(String[] args) {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            InputReader in = new InputReader(inputStream);
            PrintWriter out = new PrintWriter(outputStream);
            Task2 solver = new Task2();
            int testCount = Integer.parseInt(in.next());
            for (int i = 1; i <= testCount; i++)
                solver.solve(i, in, out);
            out.close();
        }
    
        static class Task2 {
            BigInteger C(int n, int m) {
                BigInteger ans = BigInteger.valueOf(1);
                for (int i = 1; i <= m; i++) {
                    ans = ans.multiply(BigInteger.valueOf(n - i + 1));
                }
                for (int i = 2; i <= m; i++) {
                    ans = ans.divide(BigInteger.valueOf(i));
                }
                return ans;
            }
    
            public void solve(int testNumber, InputReader in, PrintWriter out) {
                int n = in.nextInt();
                int[] a = new int[n + 1];
                int[] b = new int[n + 1];
                for (int i = 1; i <= n; i++) {
                    a[i] = in.nextInt();
                    b[a[i]] = i;
                }
                ArrayList<Integer> arr = new ArrayList<>();
                int now = 1;
                for (int i = 2; i <= n; i++) {
                    if (a[i - 1] != n && (a[i] == n || b[a[i - 1] + 1] > b[a[i] + 1])) {
                        arr.add(now);
                        now = 1;
                    } else {
                        now++;
                    }
                }
                arr.add(now);
                if (arr.size() > 26) {
                    out.println(0);
                } else {
                    int sz = arr.size();
                    BigInteger[][] dp = new BigInteger[sz + 1][27];
                    for (int i = 0; i <= sz; i++) {
                        for (int j = 0; j <= 26; j++) {
                            dp[i][j] = BigInteger.valueOf(0);
                        }
                    }
                    dp[0][0] = BigInteger.valueOf(1);
                    for (int i = 0; i < sz; i++) {
                        for (int j = 0; j < 26; j++) {
                            for (int k = 1; j + k <= 26; k++) {
                                dp[i + 1][j + k] = dp[i + 1][j + k].add(dp[i][j].multiply(C(arr.get(i) + k - 2, k - 1)));
                            }
                        }
                    }
                    // out.println(dp[sz][26]);
                    BigInteger ans = BigInteger.valueOf(0);
                    for (int i = 1; i <= 26; i++) {
                        ans = ans.add(dp[sz][i]);
                    }
                    out.println(ans);
                }
            }
    
        }
    
        static class InputReader {
            public BufferedReader reader;
            public StringTokenizer tokenizer;
    
            public InputReader(InputStream stream) {
                reader = new BufferedReader(new InputStreamReader(stream), 32768);
                tokenizer = null;
            }
    
            public String next() {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                    try {
                        tokenizer = new StringTokenizer(reader.readLine());
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
                return tokenizer.nextToken();
            }
    
            public int nextInt() {
                return Integer.parseInt(next());
            }
    
        }
    }
    809ms
  • 相关阅读:
    lhgdialogv3.13 使用点滴
    CheckBoxList 取值 及选中相关用法
    repeater 及 gridview 中绑定短日期
    数据库中日期大小的判断
    父子不同窗口间刷新传值
    子级Repeater获取父级Repeater绑定项的值
    vs.net 2010 web 项目中使用 webservice
    web打印实现方案 Lodop6.034 使用方法总结
    用 showModalDialog 方法回传数据到父页中去
    vs.net2010中使用 Ajax Control Toolkit
  • 原文地址:https://www.cnblogs.com/Roni-i/p/7586498.html
Copyright © 2011-2022 走看看