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

题解 LG P2264

时间:2020-02-21 18:02:07      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:cpp   insert   getline   RKE   int   getchar   前缀树   次数   update   

这是题解P2264

先讲一下Trie,其实Trie也名前缀树,就是说:如果Trie中某串是某串的前缀,那么我们可以共用这个串也就是这样:

插入h、hk、jc,jcfa

那么,h节点会给h和hk共用,jc串也会给jcfa共用。

对于本题来说,因为要考虑每个句子后要标记次数,所以Trie要有附加数组。

拿样例为例,我们原本会构建这样的一棵TRIE树:

技术图片

但我们只要在底下最后一个点附加一个val数组来记录次数,因为要记录次数。

那么trie就沉了这样:

int ch[N][C],tot=1;
int check[N];

怎么写也就更简单了:

#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
#define N 50005
#define rr register
#define C 27
string s,w;
int n; 
int ch[N][C],tot=1,ans;
string w1[N];
int check[N]; 
int idx(char s);
void insert(string s);
int find(string s);
char turn(char x);
int main()
{ 
  cin>>n;
  for(rr int i=1;i<=n;i++)
  {
      cin>>w1[i];
  for(rr int j=0;j<=w1[i].size()-1;j++)
      w1[i][j]=turn(w1[i][j]);
      insert(w1[i]);
  }
  int len;
  getchar();
  getline(cin,s);
  len=s.size()-1;
  for(rr int i=0;i<=len;i++)
  {
          s[i]=turn(s[i]);
        if(s[i]==. or s[i]==, or s[i]== )
        {
            if(find(w)==1)
             ans++;
            if(s[i]==.)
             for(rr int j=1;j<=n;j++)
             insert(w1[j]); 
            w="";
        }
        else
            w+=s[i];
    }
    cout<<ans;
  return 0; 
}
int idx(char x)
{
    int v;
    v=(int)(x-a);
    return v;
}
void insert(string s)
{
    int len=s.size()-1;
    int las=0,w;
    for(rr int i=0;i<=len;i++)
    {
        w=idx(s[i]);
        if(ch[las][w]==0) 
         ch[las][w]=++tot;
        las=ch[las][w];
    }
    check[las]=1; 
    return;
}
int find(string s)
{
    int len=s.size()-1;
    int las=0,w;
    for(rr int i=0;i<=len;i++)
    {
        w=idx(s[i]);
        if(ch[las][w]==0) 
         return 0; 
        las=ch[las][w];
    }
    if(check[las]==1) 
    {
     check[las]++;
     return 1;    
    }
    else return 0;
} 
char turn(char x)
{
    if(x>=A&&x<=Z) return (x+32);
    else return x;
} 

 

Update 2020.2.14 祝大家情人节快乐!

二分答案:

N方过百万,暴力碾标程

这是对不会STL+Trie的福音。

这是P2264的第2种做法。

我们想一下,题目中说了有N个可以加好感度的字符串。

众所周知,我们只需要按字典序排好序,那么N个字符串就会呈单调上升。

单调上升的话,我们就可以进行二分查找是否可以加好感度。

而二分查找的时间是logn,整个程序的时间就是O(Slogn)

其中S是字符串长度。

 

题解 LG P2264

标签:cpp   insert   getline   RKE   int   getchar   前缀树   次数   update   

原文地址:https://www.cnblogs.com/ct666rp/p/12342060.html

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