Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define SIZE 200100
- #define ALPHABET 128
- typedef struct {
- int lf, rf, parent, sl, next[ALPHABET];
- } node;
- typedef struct {
- int v, pos;
- } pointer;
- char s[SIZE], w[SIZE];
- node nodes[SIZE];
- pointer ap;
- int np, len;
- void Node(int id, int parent, int lf, int rf) {
- nodes[id].parent = parent;
- nodes[id].lf = lf;
- nodes[id].rf = rf;
- nodes[id].sl = -1;
- memset(nodes[id].next, -1, ALPHABET * sizeof(int));
- }
- pointer Pointer(int v, int pos) {
- pointer res;
- res.v = v;
- res.pos = pos;
- return res;
- }
- int getNext(int id, char c) {
- return nodes[id].next[c];
- }
- void setNext(int id, char c, int v) {
- nodes[id].next[c] = v;
- }
- int isRoot(int id) {
- return (nodes[id].lf == -1);
- }
- int length(int id) {
- return (nodes[id].rf - nodes[id].lf);
- }
- void initTree() {
- np = 0;
- len = strlen(s);
- ap = Pointer(0, 0);
- int root = np++;
- Node(root, 0, -1, -1);
- nodes[root].sl = 0;
- }
- int addVertex(int parent, int lf, int rf) {
- int id = np++;
- Node(id, parent, lf, rf);
- setNext(parent, s[lf], id);
- return id;
- }
- int split(pointer ap) {
- int down = ap.pos, up = length(ap.v) - down;
- if(down == 0) {
- return ap.v;
- }
- if(up == 0) {
- return nodes[ap.v].parent;
- }
- int id = addVertex(nodes[ap.v].parent, nodes[ap.v].lf, nodes[ap.v].lf + up);
- nodes[ap.v].lf += up;
- nodes[ap.v].parent = id;
- setNext(id, s[nodes[ap.v].lf], ap.v);
- return id;
- }
- pointer down(int v, int lf, int rf) {
- if(lf == rf) {
- return Pointer(v, 0);
- }
- v = getNext(v, s[lf]);
- if(length(v) >= (rf - lf)) {
- return Pointer(v, length(v) - (rf - lf));
- }
- return down(v, lf + length(v), rf);
- }
- int link(int v) {
- if(nodes[v].sl == -1) {
- int new_lf = nodes[v].lf;
- if(isRoot(nodes[v].parent)) {
- new_lf += 1;
- }
- nodes[v].sl = split(down(link(nodes[v].parent), new_lf, nodes[v].rf));
- }
- return nodes[v].sl;
- }
- pointer go(pointer ap, char c) {
- if(ap.pos == 0) {
- int child = getNext(ap.v, c);
- if(child != -1) {
- return Pointer(child, length(child) - 1);
- } else {
- return Pointer(-1, -1);
- }
- } else {
- if(s[nodes[ap.v].rf - ap.pos] == c) {
- return Pointer(ap.v, ap.pos - 1);
- } else {
- return Pointer(-1, -1);
- }
- }
- }
- void printTree() {
- int i;
- for(i = 0; i < np; i++) {
- printf("%d %d %d %d %d\n", i, nodes[i].lf, nodes[i].rf, nodes[i].parent, nodes[i].sl);
- }
- }
- pointer addChar(pointer ap, int i) {
- pointer new_ap = go(ap, s[i]);
- if(new_ap.v != -1) {
- return new_ap;
- }
- int id = split(ap);
- addVertex(id, i, len);
- ap = Pointer(link(id), 0);
- if(isRoot(id)) {
- return ap;
- } else {
- return addChar(ap, i);
- }
- }
- void buildTree() {
- int i;
- for(i = 0; i < len; i++) {
- ap = addChar(ap, i);
- }
- }
- int check(int v, int lf, int rf) {
- int p = nodes[v].lf;
- while(p < nodes[v].rf && lf < rf && s[p] == w[lf]) {
- ++p;
- ++lf;
- }
- if(lf == rf) {
- return 1;
- }
- if(p < nodes[v].rf) {
- return 0;
- }
- if(getNext(v, w[lf]) == -1) {
- return 0;
- }
- return check(getNext(v, w[lf]), lf, rf);
- }
- int main() {
- int tests, words, test, word;
- scanf("%d", &tests);
- for(test = 0; test < tests; test++) {
- scanf("%s", s);
- initTree();
- buildTree();
- scanf("%d", &words);
- for(word = 0; word < words; word++) {
- scanf("%s", w);
- int status = check(0, 0, strlen(w));
- if(status) {
- printf("y\n");
- } else {
- printf("n\n");
- }
- }
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment