zoukankan      html  css  js  c++  java
  • BZOJ1590:[Usaco2008 Dec]Secret Message秘密信息

    浅谈(Trie)https://www.cnblogs.com/AKMer/p/10444829.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=1590

    把秘密信息建一棵(Trie),在节点上记录经过这个结点的字符串(sum)一共有多少个(也就是以从根到当前结点为前缀的字符串一共有多少个),记录以当前节点为字符串结尾(bo)的有多少个(也就是从根开始到当前结点的字符串一共有多少个)。

    对于每一个密码,从根开始,把沿途所有的(bo)算进答案里(这些秘密信息是这条密码的前缀),最后到达的结点的(sum)加进答案里(这些秘密信息的前缀是这条密码),注意最后落脚点的(bo)要减去。

    时间复杂度:(O(sum B_i+sum C_i))

    空间复杂度:(O(sum B_i+sum C_i))

    代码如下:

    #include <cstdio>
    using namespace std;
    
    const int maxn=5e5+5;
    
    int num[maxn];
    int n,m,cnt,ans;
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    struct Trie {
    	int tot;
    	int bo[maxn];
    	int sum[maxn];
    	int son[maxn][2];
    
    	void ins() {
    		int pos=1;
    		for(int i=1;i<=cnt;i++) {
    			if(son[pos][num[i]])pos=son[pos][num[i]];
    			else pos=son[pos][num[i]]=++tot;sum[pos]++;
    		}
    		bo[pos]++;
    	}
    
    	void find() {
    		int pos=1;
    		for(int i=1;i<=cnt;i++) {
    			if(son[pos][num[i]])pos=son[pos][num[i]];
    			else return;ans+=bo[pos];
    		}
    		if(bo[pos])ans-=bo[pos];ans+=sum[pos];
    	}
    }T;
    
    int main() {
    	n=read(),m=read(),T.tot=1;
    	for(int i=1;i<=n;i++) {
    		cnt=read();
    		for(int j=1;j<=cnt;j++)
    			num[j]=read();
    		T.ins();
    	}
    	for(int i=1;i<=m;i++) {
    		cnt=read(),ans=0;
    		for(int j=1;j<=cnt;j++)
    			num[j]=read();
    		T.find();printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    什么是高可用?
    URL中两种方式传参
    Flask基本环境配置
    爬虫urlib库的一些用法
    HTML第一部分
    python中递归题
    python中重要的内置函数
    关于生成器中的send,应用移动平均值,以及yield from
    python中装饰器进阶
    一些作业
  • 原文地址:https://www.cnblogs.com/AKMer/p/10446265.html
Copyright © 2011-2022 走看看