[Persistable segment tree] [P5826] [template] sequences automata

[Persistable segment tree] [P5826] [template] sequences automata

Description

Given a sequence \ (A \) , there are \ (Q \) times asked each time a query sequence \ (B \) is not \ (A \) of the sequence

Limitations

Sequence \ (A \) no longer than \ (10 ^ 5 \) , and the length of the query sequence does not exceed \ (10 ^ 6 \) , does not exceed the number of query \ (10 ^ 5 \)

Solution

Digression: about the difficulty of solving the problem, I think probably not to purple, but can persist board segment tree is purple, so we set into purple

Algorithm \(1\)

Consider for a query sequence \ (B \) , which is provided with (A \) \ longest common subsequence \ (A \) is the subscript sequence \ (the Z \) , obviously if and only if \ ( the Z \) length \ (| B | \) when, \ (B \) is \ (a \) in sequence. Legal sequence \ (Z \) there may be more, but as long as we find the minimum length lexicographically as \ (| B | \) sequence \ (Z \) , you can explain \ (B \) is \ (a \) sub-sequences, otherwise not.

Consider the dictionary to find the smallest sequence \ (the Z \) can greedy selection, i.e. for the \ (B \) each prefix, which can be obtained corresponding to \ (the Z \) last sequence number is minimum, when the \ (B \) prefix when adding a number requiring only \ (a \) from the current \ (\ the Z) scanning continues rearward position value of the last bit of the sequence, equal to the first new sweep digital position, that is, a new \ (Z \) last sequence. And if the scan to \ (A \) is finally not found, it means that there is no legitimate \ (Z \) sequence, therefore \ (B \) instead of \ (A \) sub-sequences.

When this is the case each interrogation, to scan up \ (A \) once, so the total time complexity is \ (O (NQ + \ SUM L) \) , by Subtask \ (. 1 \) , the desired score \ (20 ~ pts \)

Algorithm \(2\)

Consider \ (A \) establishing a subsequence automaton, used to identify the \ (A \) in all sequences.

Also the use of Algorithm 1thought, for a string \ (B \) , we just found it with (A \) \ longest common subsequence in \ (A \) in the lexicographically smallest subscript sequence \ ( the Z \) , can be described \ (B \) is \ (a \) in sequence. Then for \ (A \) in every respect, when it needs to match a new number, should be transferred to the \ (A \) after the first digit for the position, apparently so as to ensure \ (Z \) lexicographic sequence is minimal. Therefore, we should maintain the transfer after adding a number for the first digit of its position on the back of each location.

We consider \ (A \) one by one from back to front position established automaton, for the first \ (i \) position, the first \ (i - 1 \) bits added \ (A_i \) should be transferred to \ (i \) , and the number should be transferred to the addition of other \ (A_i \) position into the number of post-added. Therefore pseudocode

for i : m do
  trans[n][i] <- -1
end
for i = n : 1 do
  for j = 1 : m do
    trans[i - 1][j] <- trans[i][j]
  end
  trans[i - 1][A[i]] <- i
end

Wherein \ (n-\) Representative \ (A \) length, \ (m \) Representative \ (A \) maximum values, \ (Trans \) is a two-dimensional array, on behalf of the automaton.

While a string \ (B \) when matching, simply \ (B \) along the transfer robot machines run again, if not run out of the automatic machine, the \ (B \) is \ (A \) subsequence, otherwise not.

Function check:
  pos <- 0
  ret <- true
  for i = 1 : L do
    pos <- trans[pos][B[i]]
    if pos == -1 then
      ret <- false
      break
    endif
  end
  return ret
end Func

Noting this configuration automata time complexity \ (O (nm) \) , complexity is matched \ (O (\ SUM L) \) , so the total time complexity \ (O (nm + \ sum L ) \) , by Subtask \ (. 1 \) , \ (2 \) , the desired score \ (PTS ~ 55 \) .

Algorithm \(3\)

Notes that construction automata, the first \ (i \) position to the first \ (i - 1 \) position only \ (A_i \) one is not the same, the \ (i - 1 \) bit shift can be seen as the first \ (I \) modified on the basis of the position on a transfer position, so we can use persistent forward segment tree from each array to maintain the transfer position, so that the establishment of the automatic machine time complexity \ (O (n-\ log m) \) , the time complexity is matched \ (O (\ SUM L \ log m) \) . The total time complexity \ (O ((n-+ \ L SUM) \ log m) \) , through all of the Subtask, desired points \ (100 PTS ~ \) .

Code

Algorithm \(2\)

Code from @ ** _ Jiaoyue half sprinkle flowers **

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>

#define MAXN 200010

using namespace std ;

int L, N, M, Q, S[MAXN], nxt[MAXN][102] ;

void build(){
    for (int i = 1 ; i <= M ; ++ i)
        nxt[L + 2][i] = nxt[L + 1][i] = L + 2 ;
    for (int i = L ; i ; -- i)
        memcpy(nxt[i - 1], nxt[i], sizeof(nxt[i])), nxt[i - 1][S[i]] = i ;
}
int qr(){
    char c = getchar() ;
    int res = 0 ; while (!isdigit(c)) c = getchar() ;
    while (isdigit(c)) res = (res << 1) + (res << 3) + c - 48, c = getchar() ;
    return res ;
}
int main(){
    int i, j, k, emm ;
    cin >> emm >> N >> Q >> M ; L = N ;
    for (i = 1 ; i <= L ; ++ i) scanf("%d", &S[i]) ; build() ;
    for (i = 1 ; i <= Q ; ++ i){
        N = qr() ; int st = 0, ans = 0 ;
        for (j = 1 ; j <= N ; ++ j){
            k = qr(), st = nxt[st][k] ;
            if (!st){
                while (j < N)
                    ++ j, emm = qr() ;
                ans = 1 ;
            }
//            cout << st << endl ;
        }
        printf(ans ? "No\n" : "Yes\n") ;
    }
    return 0 ;
}

Algorithm \(3\)

#include <cstdio>

template <typename T>
inline void qr(T &x) {
  char ch;
  do ch = getchar(); while ((ch > '9') || (ch < '0'));
  do x = x * 10 + (ch ^ 48), ch = getchar(); while ((ch >= '0') && (ch <= '9'));
}

const int maxn = 100005;

struct Tree {
  Tree *ls, *rs;
  int l, r, v;

  Tree(const int L, const int R) : l(L), r(R), v(-1) {
    if (l != r) {
      int mid = (l + r) >> 1;
      ls = new Tree(l, mid);
      rs = new Tree(mid + 1, r);
    }
  }

  Tree(Tree *pre, const int P, const int V) : l(pre->l), r(pre->r), v(0) {
    if (l == r) {
      v = V;
    } else {
      if (pre->ls->r >= P) {
        rs = pre->rs;
        ls = new Tree(pre->ls, P, V);
      } else {
        ls = pre->ls;
        rs = new Tree(pre->rs, P, V);
      }
    }
  }

  int query(const int x) {
    if (this->l == this->r) {
      return this->v;
    } else {
      return (this->ls->r >= x) ? this->ls->query(x) : this->rs->query(x);
    }
  }
};
Tree *rot[maxn];

int tp, n, q, m;
int MU[maxn];

int main() {
  qr(tp); qr(n); qr(q); qr(m);
  rot[n] = new Tree(1, m);
  for (int i = 1; i <= n; ++i) {
    qr(MU[i]);
  }
  for (int i = n; i; --i) {
    rot[i - 1] = new Tree(rot[i], MU[i], i);
  }
  for (int L, x, pos; q; --q) {
    L = pos = 0; qr(L);
    while ((L--) && (pos != -1)) {
      x = 0; qr(x);
      if ((pos = rot[pos]->query(x)) == -1) {
        while (L--) {
          qr(x);
        }
        break;
      }
    }
    puts((~pos) ? "Yes" : "No");
  }
  return 0;
}

appreciation

Thanks inspection problems people: @ ** _ Jiaoyue half sprinkle flower ** @ water_lift

Thanks to this article review and proofreading: @ Dusker

Guess you like

Origin www.cnblogs.com/yifusuyi/p/12052242.html