• 【洛谷P2922】Secret Message


    题目大意:给定 N 个字符串组成的字典,有 M 个询问,每次给定一个字符串,求字典中有多少个单词为给定字符串的前缀或前缀是给定的字符串。

    题解:在 trie 上维护一个 tag 表示有多少字符串以当前字符串为前缀,ed 表示从该节点到根节点之间为一个字符串。
    对于给定的字符串,在 trie 中顺序查找,在匹配的过程中累加经过节点的 ed 标记,表示有多少字符串为给定字符串的前缀。若匹配成功,则答案累加 tag 标记并减去最后一个节点的 ed 标记,防止重复计算。若匹配失败,只需输出记录的 ed 之和即可。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=5e5+10;
    
    int trie[maxn][2],tot=1,tag[maxn],ed[maxn];
    int m,n,len,s[10010];
    
    void insert(int *ss){
    	int now=1;
    	for(int i=1;i<=len;i++){
    		int ch=ss[i];
    		if(!trie[now][ch])trie[now][ch]=++tot;
    		now=trie[now][ch],++tag[now];
    	}
    	++ed[now];
    }
    void query(int *ss){
    	int now=1,ret=0;
    	for(int i=1;i<=len;i++){
    		int ch=ss[i];
    		if(!trie[now][ch]){
    			printf("%d
    ",ret);
    			return;
    		}
    		now=trie[now][ch];
    		ret+=ed[now];
    	}
    	printf("%d
    ",ret+tag[now]-ed[now]);
    }
    
    int main(){
    	scanf("%d%d",&m,&n);
    	for(int i=1;i<=m;i++){
    		scanf("%d",&len);
    		for(int j=1;j<=len;j++)scanf("%d",&s[j]);
    		insert(s);
    	}
    	for(int i=1;i<=n;i++){
    		scanf("%d",&len);
    		for(int j=1;j<=len;j++)scanf("%d",&s[j]);
    		query(s);
    	}
    	return 0;
    }
    
  • 相关阅读:
    T4设计时模板调试
    MVC开发T4代码生成之一文本模板基础
    经典选项卡
    IE 调试工具 Utilu IE Collection:IE5.5、6.0、7.0, 8.0…各版本浏览器兼容性测试工具
    滚动读行!
    自定义标签的用法、支持IE6
    jQuery 参数传递例子
    IMG在IE6下不能HOVER的解决办法!
    点击渐变弹出层
    操作滚动条滚动到指定位置
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10824463.html
Copyright © 2020-2023  润新知