NAIPC2018 Pre?x Free Code(字典树)

Posted albert-biu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NAIPC2018 Pre?x Free Code(字典树)相关的知识,希望对你有一定的参考价值。

题目描述

Consider n initial strings of lower case letters, where no initial string is a prefix of any other initial string. Now, consider choosing k of the strings (no string more than once), and concatenating them together. You can make this many such composite strings:
n × (n ? 1) × (n ? 2) × . . . × (n ? k + 1)
Consider sorting all of the composite strings you can get via this process in alphabetical order. You are given a test composite string, which is guaranteed to belong on this list. find the position of this test composite string in the alphabetized list of all composite strings, modulo 109 +7. The first composite string in the list is at position 1.

 

输入

Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. Each test case will begin with a line with two integers, first n and then k(1 ≤ k ≤ n), where n is the number of initial strings, and k is the number of initial strings you choose to form composite strings. The upper bounds of n and k are limited by the constraints on the strings, in the following paragraphs.
Each of the next n lines will contain a string, which will consist of one or more lower case letters a..z. These are the n initial strings. It is guaranteed that none of the initial strings will be a prefix of any other of the initial strings.
finally, the last line will contain another string, consisting of only lower case letters a..z. This is the test composite string, the position of which in the sorted list you must find. This test composite string is guaranteed to be a concatenation of k unique initial strings.
The sum of the lengths of all input strings, including the test string, will not exceed 106 letters.

 

输出

Output a single integer, which is the position in the list of sorted composite strings where the test composite string occurs. Output this number modulo 109 + 7.

 

样例输入

5 3
a
b
c
d
e
cad
#include <iostream>

#include <stdio.h>
#include <string>
#include <map>
#include <algorithm>
#include <vector>

using namespace std;

const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
#define ull unsigned long long
#define ll long long
int n, k;
string list[maxn];
map<string, int> Map;
long long ans[maxn];
int ID;

class node {
public:
    bool isWord;
    int rank;
    node **next;
    int myid;

    node() {
        isWord = false;
        next = new node *[26];
        for (int i = 0; i < 26; i++) {
            next[i] = nullptr;
        }
        myid = ID++;
    }

    void insert(string s, int k, int myrank) {
        if (k == s.length()) {
            isWord = true;
            rank = myrank;
            return;
        }
        if (next[s[k] - a] == nullptr) {
            next[s[k] - a] = new node();
        }
        next[s[k] - a]->insert(s, k + 1, myrank);
    }
};

node *mytrie;
vector<int> initPerm;

void getPerm(string item) {
    node *ptr = mytrie;
    for (int i = 0; i < item.length(); i++) {
        ptr = ptr->next[item[i] - a];
        if (ptr->isWord) {
            initPerm.push_back(ptr->rank);
            ptr = mytrie;
        }
    }
}

class bit {
public:
    int n;
    int v[maxn];

    int sum(int x) {
        return x < 0 ? 0 : (v[x] + sum((x & (x + 1)) - 1));
    }

    void inc(int p, int x) {
        for (int i = p; i < n; i |= (i + 1)) v[i] += x;
    }

    bit(int N) {
        n = N;
        //v = new int[n];
    }
};

string item;

int main() {
    //freopen("C:\Users\albert\Desktop\7622\prefix-2028.in", "r", stdin);
    //freopen("input.txt", "r", stdin);
    cin >> n >> k;
    if(n==1&&k==1){
        cout<<1<<endl;
        return 0;
    }
    for (int i = 0; i < n; i++) {
        cin >> list[i];
    }
    sort(list, list + n);
    for (int i = 0; i < n; i++) {
        Map[list[i]] = i;
    }
    ans[0] = 1;
    for (int i = 1; i < k; i++) {
        ans[i] = (ans[i - 1] * (n - k + i)) % mod;
    }
    mytrie = new node();
    for (int i = 0; i < n; i++) {
        mytrie->insert(list[i], 0, i);
    }
    cin >> item;
    long long res = 0;
    getPerm(item);
    bit *mybit = new bit(n + 1);
    for (int i = 0, j = k - 1; i < initPerm.size(); i++, j--) {
        int nextItem = initPerm[i];
        int sub = mybit->sum(nextItem + 1);
        int real = nextItem - sub;
        res = (res + real * ans[j] + mod) % mod;
        mybit->inc(nextItem + 1, 1);
        //cout << real << endl;

    }
    printf("%lld
", (res + 1) % mod);
    return 0;
}

 

样例输出

26








以上是关于NAIPC2018 Pre?x Free Code(字典树)的主要内容,如果未能解决你的问题,请参考以下文章

2017 NAIPC A:Pieces of Parentheses

线段树+扫描线 NAIPC 2019 Intersecting Rectangles

NAIPC 2016 K-Inversions I-Tourists

code1540 银河英雄传说

2018-03-20 Linux学习

code标签和pre标签