hdu1251:统计难题

Pre

尝试着不看别人的代码自己打了一遍,结果发现有很多可以优化的地方。

Solution

略(没有为什么)

Code

#include<bits/stdc++.h>
using namespace std;
const int N = 3000000 + 5;
int cnt = 1, son[N], bro[N], num[N], lgh[N];
char info[N][15];
char tmp[15];
int len;
inline void split (int u, int v) {
	cnt++;
	for (int i = v + 1; i <= lgh[u]; ++i) {
		info[cnt][i - v] = info[u][i];
	}
	lgh[cnt] = lgh[u] - v;
	lgh[u] = v;
	son[cnt] = son[u];
	son[u] = cnt;
	num[cnt] = num[u];
	num[u] = 0;
}
inline void insert (int u, int p) {
	while (1) {
		for (int i = son[p]; i != -1; i = bro[i]) {
			if (info[i][1] == tmp[u + 1]) {
				for (int j = 2; j <= min (lgh[i], len - u); ++j) {
					if (info[i][j] != tmp[u + j]) {
						j--;
						split (i, j);
						int now = son[i];
						cnt++;
						bro[now] = cnt;
						for (int k = u + j + 1; k <= len; ++k) {
							info[cnt][k - (u + j)] = tmp[k];
						}
						lgh[cnt] = len - (u + j);
						num[cnt] = 1;
						return ;
					}
				}
				if (lgh[i] == len - u) {
					num[i]++;
					return ;
				}
				else if (lgh[i] < len - u) {
					u += lgh[i];
					p = i;
					goto next;
				}
			}
		}
		cnt++;
		bro[cnt] = son[p];
		son[p] = cnt;
		for (int i = u + 1; i <= len; ++i) {
			info[cnt][i - u] = tmp[i];
		}
		lgh[cnt] = len - u;
		num[cnt] = 1;
		return ;
		next:;
	}
}
void dfs (int u) {
	for (int i = son[u]; i != -1; i = bro[i]) {
		dfs (i);
		num[u] += num[i];
	}
}
inline int query (int u, int p) {
	while (1) {
		for (int i = son[p]; i != -1; i = bro[i]) {
			if (info[i][1] == tmp[u + 1]) {
				for (int j = 2; j <= min (lgh[i], len - u); ++j) {
					if (info[i][j] != tmp[u + j]) {
						return 0;
					}
				}
				if (lgh[i] >= len - u) {
					return num[i];
				}
				else {
					p = i;
					u += lgh[i];
					goto next;
				}
			}
		}
		return 0;
		next:;
	}
}
int main () {
	memset (son, -1, sizeof (son));
	memset (bro, -1, sizeof (bro));
	while (1) {
		gets (tmp + 1);
		if (!tmp[1]) {
			break;
		}
		len = strlen (tmp + 1);
		tmp[++len] = 'X';
		insert (0, 1);
	}
	dfs (1);
	while (scanf ("%s", tmp + 1) == 1) {
		len = strlen (tmp + 1);
		printf ("%d
", query (0, 1));
	}
	return 0;
}
#include <iostream>
#include <stdio.h>
using namespace std;

int trie[1000010][26];    //数组形式定义字典树,值存储的是下一个字符的位置
int num[1000010]={0};    //附加值,以某一字符串为前缀的单词的数量
int pos = 1;

void Insert(char word[])    //在字典树中插入某个单词
{
    int i;
    int c = 0;
    for(i=0;word[i];i++){
        int n = word[i]-'a';
        if(trie[c][n]==0)    //如果对应字符还没有值
            trie[c][n] = pos++;
        c = trie[c][n];
        num[c]++;
    }
}
int Find(char word[])    //返回以某个字符串为前缀的单词的数量
{
    int i;
    int c = 0;
    for(i=0;word[i];i++){
        int n = word[i]-'a';
        if(trie[c][n]==0)
            return 0;
        c = trie[c][n];
    }
    return num[c];
}

int main()
{
    char word[11];
    while(gets(word)){
        if(word[0]==NULL)    //空行。gets读入的回车符会自动转换为NULL。
            break;
        Insert(word);
    }
    while(gets(word))
        printf("%d
",Find(word));
    return 0;
}

第二个代码摘自https://www.cnblogs.com/yym2013/p/3780621.html

Conclusion

暂无。

原文地址:https://www.cnblogs.com/ChiTongZ/p/11197594.html