11年福州 E

来源:互联网 发布:羊毛含量 知乎 编辑:程序博客网 时间:2024/05/17 03:25

/*
这题卡内存实在是太狗了……
思路很明确,就是几个算法杂糅在一起

刚开始粗糙的思路是建一个二叉搜索树,再按照中序遍历把树的点存一遍,最后跑一遍KMP然而    二叉搜索树用的set和数组revg,revg[i]存储对于值为i的节点下标    中序遍历用dfs做本题卡内存,正确的做法应该是    二叉搜索树用的map,因为map是有序且按照第一维升序排列,故可以直接替换revg和set的作用    中序遍历用手工栈做失分点:    1.卡内存:        出现情况可能是递归爆栈、系统STL库存储空间需要过大、开的数组过多过大学习的地方:    1.map有序,可以用来二分查找    2.卡内存时处理办法    3.递归爆栈时可以改成手工栈操作

*/

#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <cstdlib>#include <string>#include <vector>#include <iterator>#include <queue>#include <utility>#include <set>#include <stack>#include <map>using namespace std;#define mp make_pair#define fi first#define se secondconst int MAXN = 600000 + 5;int ne[MAXN][2];int nodecnt;int g[MAXN];//, revg[MAXN];//, vis[MAXN];char out[MAXN * 3];//int fa[MAXN];int outcnt;int fail[7000 + 5], n;char mat[7000 + 5];//set<int>S;map<int,int>revg;int sta[MAXN];int num[MAXN];void dfs(int mark){    memset(num, 0, sizeof num);    int head = 1, rear = 0;    sta[++rear] = mark;    while(head <= rear) {        int u = sta[rear--];//        printf("u = %d\n", u); system("pause");        out[outcnt++] = (g[u] % 2) + '0';        if(num[u] == 0) {            num[u]++;            if(ne[u][0] != -1) {                sta[++rear] = u;                sta[++rear] = ne[u][0];                continue;            }        }        if(num[u] == 1) {            num[u]++;            if(ne[u][1] != -1) {                sta[++rear] = u;                sta[++rear] = ne[u][1];            }        }    }}//int const MAXT2 = MAXN * 2;void failure(){    fail[0] = 0;    int j = fail[0];    int len = strlen(mat);    for(int i=1; i<len; i++){        while(j && mat[i]!=mat[j])            j = fail[j];        if(mat[i] == mat[j]) j++;        fail[i + 1] = j;    }}int match(){    int res = 0,now = 0,j=0;    int n = strlen(mat);    int m = outcnt;    while(now + n - j <= m){        if(j == n){            res ++;            j = fail[j];        }        while(j && mat[j]!=out[now])  j = fail[j];        if(mat[j] == out[now]){            j++;    now++;        }        else{            now++;        }    }    return res;}void init(int i){for(int u = 0 ; u < 2 ; u++) ne[i][u] = -1;}int main(){    int T; scanf("%d", &T);    for(int cas = 1 ; cas <= T ; cas++) {        revg.clear();//        S.clear();        scanf("%d", &n);        outcnt = 0;        memset(ne, -1, sizeof ne);        for(int i = 1 ; i <= n ; i++) scanf("%d", &g[i]);        revg[0] = 0;        init(1);        init(0);//        vis[0] = 0;//        node[1].init();        revg[g[1]] = 1;        for(int i = 2 ; i <= n ; i++) {//            if(i == 2) {//                printf("node[1] = %d %d\n", node[1].ne[0], node[1].ne[1]);//            }            map<int,int>::iterator it = revg.lower_bound(g[i]);            int t1, t2;            if(it == revg.end()) {                it--;                t2 = 0;                t1 = (*it).se;            }            else {                t2 = (*it).se;                if(it == revg.begin()) t1 = 0;                else {                    it--;                    t1 = (*it).se;                }            }//            t1 = revg[t1], t2 = revg[t2];            int parent;            if(t1 != 0 && ne[t1][1] == -1) parent = t1, ne[t1][1] = i;            else parent = t2, ne[t2][0] = i;//            printf("t1 = %d, ne[t1] = %d %d, t2 = %d, ne[t2] = %d %d\n", t1, ne[t1][0], ne[t1][1], t2, ne[t2][0], ne[t2][1]);//            node[i].init();            init(i);            revg[g[i]] = i;//            fa[i] = parent;//            S.insert(g[i]);        }//        for(int i = 1; i <= n ; i++) {//            printf("i = %d, u = %d, ne = %d %d\n", i, g[i], ne[i][0], ne[i][1]);//        }//        sort(g + 1, g + 1 + n);        dfs(1);        out[outcnt] = '\0';//        printf("out = %s\n", out);        scanf("%s", mat);        failure();        int res = match();        printf("Case #%d: %d\n", cas, res);    }    return 0;}
0 0
原创粉丝点击