CF1320 Div1 D.Reachable Cuerdas 题 解

Sujeto al efecto

Dada una longitud \ (n \) 01 cadena \ (S \) , cada uno de tres posiciones sucesivas que puede hacer una cadena: \ (011 \ rightarrow 110 \) , \ (110 \ rightarrow 011 \) operación.

Hay \ (Q \) los tiempos de consulta, consulta dada cada dos sub-cadenas de igual longitud, preguntándole si desea cambiar de una cadena a otra cadena.

solución del problema

En primer lugar, nos encontramos con que la operación no cambia la \ (1 \) número. Prefijo y puede ser determinada por primera (1 \) \ número son iguales.

Si una cadena no aparece al lado de dos \ (1 \) , tan fácil de conseguir que no se puede hacer ninguna acción efectiva, directa determinar si la misma. Este paso se puede dispersar o sa sam o lograr.

De lo contrario, también encontramos un nuevo invariante, es decir, un poco extraño (subcadena es poco extraño) \ (1 \) número y un poco incluso (1 \) \ número no cambia! Por lo tanto, se calculó el prefijo y el bit impar es determinado dos cadenas \ (1 \) , y determina entonces si el mismo

para

presentar

WA5 de conseguir buenos grados!

Esto nos da una lección es simple de usar invariantes no puede ser condiciones correctas y suficientes.

Necesitamos una idea maravillosa.

El \ (0 \) como el villano, \ (1 \) como espacio abierto. Cada operación puede entenderse como dos unidades móviles a una longitud villano, sin cambiar la posición relativa entre el malo.

Por lo tanto, cada uno de izquierda a derecha ubicación paridad villano es constante.

Proporcionada cadena de consulta \ ([L_1, R_1], [L_2, R_2] \) , la primera de dos sub-secuencia determina \ (0 \) número son iguales. Si son iguales, se les conoce como \ (K \) . Dispuestos de izquierda a derecha la primera cadena de \ (I \) un \ (0 \) es el S posición es \ (a_i \) , la segunda cadena es \ (b_i \) .

condición necesaria y suficiente es: para cualquier \ (i \) , \ (a_i - L_1 \ equiv b_i - L_2 (\ MOD 2) \) !

(En cuanto a la adecuación de las condiciones, tarjeta muy buena, y no escriben)

Cada uno de nosotros S \ (0 \) todos juntos, a continuación, si el \ (0 \) subíndice es un número impar, de relleno en esta posición \ (1 \) , de lo contrario rellene \ (0 \) , recuerde la nueva cadena es \ (T_1 \) , esta nueva cadena \ (01 \) son intercambiables, la forma \ (T_2 \) .

A \ (T = T_1T_2 \) para construir una matriz sufijo o sufijos autómatas. Siempre pregunte a la pregunta es \ (T \) de las dos sub-cadenas son iguales.

Este es un problema clásico.

#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << (x) << endl
using namespace std;
 
const int N = 200005, K = 25;
 
int n, q, len[N << 2], par[N << 2], last = 0, cnt = 0;
char str[N];
map<char, int> ch[N << 2];
void extend (char c) {
    int p = last, np = ++cnt;
    len[np] = len[p] + 1;
    for (; ~p && !ch[p][c]; p = par[p]) ch[p][c] = np;
    if (p < 0) par[np] = 0;
    else {
        int q = ch[p][c];
        if (len[q] == len[p] + 1) par[np] = q;
        else {
            int nq = ++cnt;
            ch[nq] = ch[q], len[nq] = len[p] + 1;
            par[nq] = par[q], par[q] = par[np] = nq;
            for (; ~p && ch[p][c] == q; p = par[p]) ch[p][c] = nq;
        }
    }
    last = np;
}
 
int tot = 0, id[N << 1], fa[N << 2][K], Log2[N << 2];
int zero[N << 1], pos[N];
 
int find_pos (int l, int r) {
    int u = id[r];
    for (int i = Log2[cnt]; i >= 0; i--) {
        if (~fa[u][i] && len[fa[u][i]] > r - l) u = fa[u][i];
    }
    return u;
}
 
int main () {
    scanf("%d%s", &n, &str);
    par[0] = -1, len[0] = 0;
    for (int i = 0; i < n; i++) {
        if (str[i] == '0') {
            pos[tot] = i;
            zero[tot++] = i & 1;
        }
    }
    
 
    for (int i = 0, j = 0; i < n; i++) {
        if (str[i] == '0') {
            zero[tot + j] = i & 1 ^ 1;
            j++;
        }
    }
 
    for (int i = 0; i < (tot << 1); i++) extend(zero[i] + '0'), id[i] = last;
 
    Log2[1] = 0;
    for (int i = 2; i <= cnt; i++) Log2[i] = Log2[i >> 1] + 1;
    for (int i = 0; i <= cnt; i++) fa[i][0] = par[i];
    for (int i = 1; i <= Log2[cnt]; i++) {
        for (int j = 0; j <= cnt; j++) {
            if (fa[j][i - 1] < 0) fa[j][i] = -1;
            else fa[j][i] = fa[fa[j][i - 1]][i - 1];
        }
    }
 
    scanf("%d", &q);
    for (int i = 0; i < q; i++) {
        int l1, l2, len;
        scanf("%d%d%d", &l1, &l2, &len), l1--, l2--;
 
        int L1 = lower_bound(pos, pos + tot, l1) - pos, R1 = lower_bound(pos, pos + tot, l1 + len) - pos;
        int L2 = lower_bound(pos, pos + tot, l2) - pos, R2 = lower_bound(pos, pos + tot, l2 + len) - pos;
 
        bool flag = true;
        if (R1 - L1 != R2 - L2) flag = false;
        if (l1 & 1) L1 += tot, R1 += tot;
        if (l2 & 1) L2 += tot, R2 += tot;
        if (L1 < R1 && L2 < R2 && find_pos(L1, R1 - 1) != find_pos(L2, R2 - 1)) flag = false;
        if (flag) puts("Yes");
        else puts("No");
    }
    return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/mathematician/p/12516909.html
Recomendado
Clasificación