zoukankan      html  css  js  c++  java
  • 洛谷 [USACO08DEC]Secret Message G(01字典树)

    传送门


    解题思路

    把每一个信息插入01字典树中,用vis[i]表示有多少个信息经过这个点,用vis2[i]表示有多少信息以i这个点结尾。

    注意vis中不包含以其结尾的点。

    然后对于每一条暗号,跑字典树,经过的点加上vis2[now],结束时加上vis[now],注意当因为匹配不到结束时不能加vis,只有到长度len时加上vis。

    感觉说的不是很清楚,看代码吧。

    AC代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<iomanip>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=500005;
     8 int n,m,a[maxn],ch[maxn][3],vis[maxn],cnt=1,len,vis2[maxn];
     9 void insert(int len){
    10     int now=1;
    11     for(int i=1;i<=len;i++){
    12         if(!ch[now][a[i]]) ch[now][a[i]]=++cnt;
    13         now=ch[now][a[i]];
    14         vis[now]++;
    15     }
    16     vis2[now]++;
    17     vis[now]--;//注意 
    18     return;
    19 }
    20 void query(int len){
    21     int now=1,ans=0;
    22     for(int i=1;i<=len;i++){
    23         if(ch[now][a[i]]) now=ch[now][a[i]];
    24         else{
    25             ans-=vis[now];//注意 
    26             break;
    27         }
    28         ans+=vis2[now];
    29     }
    30     ans+=vis[now];
    31     printf("%d
    ",ans);
    32     return;
    33 }
    34 int main(){
    35     cin>>n>>m;
    36     for(int i=1;i<=n;i++){
    37         cin>>len;
    38         for(int j=1;j<=len;j++){
    39             scanf("%d",&a[j]);
    40         }
    41         insert(len);
    42     }
    43     for(int i=1;i<=m;i++){
    44         cin>>len;
    45         for(int j=1;j<=len;j++){
    46             scanf("%d",&a[j]);
    47         }
    48         query(len);
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    Java的常用API之System类简介
    Java的常用API之Date类简介
    Java的常用API之Object类简介
    数据库知识总结(全)
    学习:浏览器访问网站的总流程
    学习:TCP/UDP协议分析(TCP四次挥手)
    学习:TCP/UDP协议分析(TCP三次握手)
    学习:ICMP协议
    实现:ARP探测存活主机
    学习:ARP协议/数据包分析
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14257811.html
Copyright © 2011-2022 走看看