zoukankan      html  css  js  c++  java
  • [2015hdu多校联赛补题]hdu5384 Danganronpa

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384

    题意:函数f(A, B)定义:A、B为字符串,f(A, B)为A中有多少个不同的B(ex:f("ababa", "aba")==2   f("ababa", "bab")==1),现在给你一组A串,一组B串,问你对每个A串的是多少

    解:ac自动机模板题,可以把A串用'z'+1,连成一个串处理起来比较方便

      1 /*
      2  * Problem:  hdu5384 Danganronpa
      3  * Author:  SHJWUDP
      4  * Created Time:  2015/8/13 星期四 14:38:23
      5  * File Name: 1006.cpp
      6  * State: Accepted
      7  * Memo: ac自动机
      8  */
      9 #include <iostream>
     10 #include <cstdio>
     11 #include <vector>
     12 #include <cstring>
     13 #include <algorithm>
     14 #include <queue>
     15 
     16 using namespace std;
     17 
     18 const int MaxA=1e5+7;
     19 const int MaxB=7e5+7;
     20 
     21 const int SIGMA_SIZE=27;
     22 
     23 struct AhoCorasickAutomata {
     24     int ch[MaxB][SIGMA_SIZE];
     25     int val[MaxB];
     26     int sz;
     27     int f[MaxB], last[MaxB];
     28 
     29     int newNode() {
     30         memset(ch[sz], 0, sizeof(ch[sz]));
     31         val[sz]=0;
     32         return sz++;
     33     }
     34 
     35     void init() {
     36         sz=0;
     37         newNode();
     38     }
     39 
     40     int id(char c) { 
     41         return c-'a'; 
     42     }
     43 
     44     void insert(char* p) {
     45         int u=0;
     46         while(*p) {
     47             int c=id(*p++);
     48             if(!ch[u][c]) ch[u][c]=newNode();
     49             u=ch[u][c];
     50         }
     51         val[u]++;
     52     }
     53 
     54     void getFail() {
     55         queue<int> Q;
     56         f[0]=0;
     57         for(int c=0; c<SIGMA_SIZE; c++) {
     58             int u=ch[0][c];
     59             if(u) { f[u]=0; Q.push(u); last[u]=0; }
     60         }
     61 
     62         while(!Q.empty()) {
     63             int r=Q.front(); Q.pop();
     64             for(int c=0; c<SIGMA_SIZE; c++) {
     65                 int u=ch[r][c];
     66                 if(!u) { ch[r][c]=ch[f[r]][c]; continue; }
     67                 Q.push(u);
     68                 int v=f[r];
     69                 while(v && !ch[v][c]) v=f[v];
     70                 f[u]=ch[v][c];
     71                 last[u]=val[f[u]]?f[u]:last[f[u]];
     72             }
     73         }
     74     }
     75 
     76     long long dealAns(int u) {
     77         long long res=0;
     78         while(u) {
     79             res+=val[u];
     80     //        val[u]=0;
     81             u=last[u];
     82         }
     83         return res;
     84     }
     85 
     86     void find(char * T, long long * ans) {
     87         int u=0;
     88         int pos=1;
     89         long long sum=0, ltsum=0;
     90         for(int i=0; T[i]; i++) {
     91             int c=id(T[i]);
     92             u=ch[u][c];
     93             if(val[u]) sum+=dealAns(u);
     94             else if(last[u]) sum+=dealAns(last[u]);
     95             if(T[i]=='z'+1) {
     96                 ans[pos++]+=sum-ltsum;
     97                 ltsum=sum;
     98             }
     99         }
    100     }
    101 } ac;
    102 
    103 int n, m;
    104 char str[MaxB];
    105 long long ans[MaxA];
    106 char gogogo[MaxA];
    107 int main() {
    108 #ifndef ONLINE_JUDGE
    109     freopen("in", "r", stdin);
    110     //freopen("out", "w", stdout);
    111 #endif
    112     int T;
    113     scanf("%d", &T);
    114     while(T--) {
    115         scanf("%d%d", &n, &m);
    116         int len=0;
    117         for(int i=0; i<n; i++) {
    118             scanf("%s", str+len);
    119             while(str[len]) len++;
    120             str[len++]='z'+1;
    121         }
    122         str[len]='';
    123         ac.init();
    124         for(int i=0; i<m; i++) {
    125             scanf("%s", gogogo);
    126             ac.insert(gogogo);
    127         }
    128         ac.getFail();
    129         memset(ans, 0, sizeof(ans));
    130         ac.find(str, ans);
    131         for(int i=1; i<=n; i++) {
    132             printf("%I64d
    ", ans[i]);
    133         }
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    JS案例
    JS案例--Tab栏切换
    currentBackgroundImage:获取按钮背景图片
    笔记:UITextView内容垂直居中方法
    笔记:载入viewcontroller的几种方式
    沙盒文件的创建(简单举例)
    笔记:iOS随机数与随机数据集
    四种传值方法(通知、block、属性、NSUserDefaults)
    笔记:沙盒文件的拷贝
    笔记:iOS字符串的各种用法(字符串插入、字符串覆盖、字符串截取、分割字符串)(别人的代码直接复制过来的,我脸皮有点厚)
  • 原文地址:https://www.cnblogs.com/shjwudp/p/4727947.html
Copyright © 2011-2022 走看看