码迷,mamicode.com
首页 > 其他好文 > 详细

P2922 [USACO08DEC]秘密消息Secret Message

时间:2018-09-09 14:44:44      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:names   ||   ring   har   while   包含   +=   bsp   sdi   

P2922 [USACO08DEC]秘密消息Secret Message

Trie

Trie典型统计题

在这题中,我们不是单纯的统计一个串是否是另一个串的前缀,而要统计数量。

在这里,我们引入一个tot标记,表示有多少串包含这个节点(不累计串的结尾)

当询问的串在路径上的u点时,加上的是a[ u ].end,表示有多少串是询问串的前缀

当询问的串走到树外时,停止统计,表示已经找不到符合前缀条件的串了

当询问的串在树内u点结束时,加上的是a[ u ].tot,表示询问串是多少个串的前缀

end.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
inline int Int(){
    char c=getchar(); int x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x;
} 
struct data{
    int nxt[2],tot,end;
}a[500002];
int n,m,ans,cnt;
inline void insert(){ //普通的向Trie内插入单词操作
    int u=0,len; len=Int();
    for(int i=0;i<len;++i){
        int p=Int();
        if(!a[u].nxt[p]) a[u].nxt[p]=++cnt;
        ++a[u].tot; //tot标记
        u=a[u].nxt[p];
        
    }++a[u].end; //end不能tot重复
}
inline void query(){
    int u=0,len; len=Int();
    bool useless=0; ans=0;
    for(int i=0;i<len;++i){
        int p=Int();
        if(!a[u].nxt[p]||useless) {useless=1; continue;} //跑到树外就不需要统计了
        u=a[u].nxt[p];
        ans+=a[u].end;
    }
    if(!useless) ans+=a[u].tot; //整个串都在树内就加上tot
    printf("%d\n",ans);
}
int main(){
    m=Int(); n=Int();
    for(int i=1;i<=m;++i) insert();
    for(int i=1;i<=n;++i) query();
    return 0;
}

 

P2922 [USACO08DEC]秘密消息Secret Message

标签:names   ||   ring   har   while   包含   +=   bsp   sdi   

原文地址:https://www.cnblogs.com/kafuuchino/p/9612662.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!