hdu 4125 Moles

来源:互联网 发布:youtube翻墙软件下载 编辑:程序博客网 时间:2024/05/21 09:03

这几天在做北大出的现场赛题,崩溃。

今天做的11年福州的现场赛题,俩字,呵呵。。。

好几道都是各种算法糅合啊啊啊啊。。。


这个题,比较恶心了,DFS不能用系统栈,得自己写,好吧。不算神马。建二叉查找树不能用普通方法,我用的是map,刚才搜题解好多用线段树的,map足以。

我将数字所在的结点(结构体,左孩子,右孩子的那个结构体)编号存入map,比如你要插入6,之前已经插入了2,3,5,8,那么可以发现,6要么在5的右子树的第一个结点,要么在8的左子树第一个结点(自己证明)。所以,我在map中查找到5,8对应的编号(只会有一种情况满足),然后直接在这个编号的结点上插入。很省时间。


最后DFS后还需要个KMP,我实在无力吐槽了。。。


#include <set>#include <map>#include <queue>#include <stack>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <limits.h>#include <string.h>#include <string>#include <algorithm>#define MID(x,y) ( ( x + y ) >> 1 )#define L(x) ( x << 1 )#define R(x) ( x << 1 | 1 )#define FOR(i,s,t) for(int i=(s); i<(t); i++)#define FORD(i,s,t) for(int i=(s-1); i>=t; i--)#define BUG puts("here!!!")#define STOP system("pause")#define file_r(x) freopen(x, "r", stdin)#define file_w(x) freopen(x, "w", stdout)using namespace std;const int MAX = 600005;struct NODE{int num;NODE* left, *right;};NODE node[MAX*2];NODE *root;int cnt;int len;map<int,int> m;void init() {m.clear();root = NULL;cnt = len = 0;}char s[MAX*2];char pat[7005];int insert(NODE* &root, int num) {if( root == NULL ) {node[cnt].num = num;node[cnt].left = NULL;node[cnt].right = NULL;root = &node[cnt];return cnt++;}if( num < root->num )return insert(root->left, num);elsereturn insert(root->right, num);}char tochar(int num) {return '0' + num%2;}void travel(NODE *root) {if( root == NULL )return ;s[len++] = tochar(root->num);travel(root->left);if( root->left )s[len++] = tochar(root->num);travel(root->right);if( root->right )s[len++] = tochar(root->num);}int pp[MAX];bool t[MAX*2];int stk[MAX*2];int top;void travel(int root) {memset(t, 0, sizeof(t));top = 0;stk[top++] = 0;while( top > 0 ) {int node_num = stk[top-1];top--;int num = node[node_num].num;s[len++] = tochar(num);if( t[node_num] )continue;t[node_num] = true;if( node[node_num].right || node[node_num].left )stk[top++] = node_num;if( node[node_num].right ) {int num = node[node_num].right->num;stk[top++] = pp[ num ];}if( node[node_num].right && node[node_num].left )stk[top++] = node_num;if( node[node_num].left ) {int num = node[node_num].left->num;stk[top++] = pp[ num ];}}}void kmp2(char *a, int m){    pp[1] = 0;    int j = 0;    for(int i = 2; i <= m; ++i)    {        while( (j > 0)  && (a[j+1] != a[i]))            j = pp[j];        if( a[j+1] == a[i] ) ++j;        pp[i] = j;    }}int kmp1(char *x, char *a, int n, int m){    int j = 0;    int cnt = 0;    for(int i = 1; i <= n; ++i)    {        while( (j > 0) &&  (a[j+1] != x[i]))            j = pp[j];        if( a[j+1] == x[i] )            ++j;        if(j == m){        cnt++;            j = pp[j];        }    }    return cnt;}int ans() {kmp2(pat-1, strlen(pat));return kmp1(s-1, pat-1, strlen(s), strlen(pat)); }int insert_(int node_num, int num) {NODE* root = &node[node_num];node[cnt].num = num;node[cnt].left = NULL;node[cnt].right = NULL;int pos = cnt++;pp[num] = pos;m[num] = pos;return pos;}int main() {int ncases, n, num;map<int,int>::iterator it;scanf("%d", &ncases);for(int ind=1; ind<=ncases; ind++) {init();scanf("%d", &n);FOR(i, 0, n) {scanf("%d", &num);if( m.size() == 0 ) {int pos = insert(root, num);m[num] = pos;continue;}it = m.begin();if( it->first > num ) {int pos = insert_(it->second, num);node[it->second].left = &node[pos];continue;}it = m.end();it--;if( it->first < num ) {int pos = insert_(it->second, num);node[it->second].right = &node[pos];continue;}it = m.lower_bound(num);int ns = it->second;if( node[ns].left == NULL ) {int pos = insert_(ns, num);node[ns].left = &node[pos];continue;}if( it == m.begin() ) continue;it--;ns = it->second;if( node[ns].right == NULL ) {int pos = insert_(ns, num);node[ns].right = &node[pos];continue;}}scanf("%s", pat);travel(0);s[len++] = '\0';printf("Case #%d: %d\n", ind, ans());}return 0;}


原创粉丝点击