题意:给你一个字符串和m个询问,问你l,r这个区间内出现过多少字串。

连接:http://acm.hdu.edu.cn/showproblem.php?pid=4622

网上也有用后缀数组搞得、

思路(虎哥):用字典树把每一个字符串对应成一个整数 相同的字符串对应到相同的整数上

把所用的串对应的整数放在一个数组里 比如书字符串s[l...r]对应的整数是 k

那么二维数组 [l][r] 就等于k

假设一个对应好的二维数组  左下角是原点

3     4     5     2

2     3     4     0

1     6     0     0

2     0     0     0

这样求解 从l到r的不同字符串的个数 其实就是求 从[l][r] 到右下角所在的矩阵所包含不同整数的个数(不包括0)

这里需要一定的去重处理 处理后是

-1    0    1     1

0     1    1     0

1     1    0     0

1     0    0     0

然后一边dp就可以求出所有答案(因为是求一个矩形矩阵,所以我用了一个二维树状数组做的,感觉好慢- -。)

注意常用的next[26]写法的字典树有可能超内存 要优化

代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <stdlib.h>
  6 #include <vector>
  7 #include <queue>
  8 #define loop(s,i,n) for(i = s;i < n;i++)
  9 #define cl(a,b) memset(a,b,sizeof(a))
 10 #define lowbit(x) x&-x
 11 using namespace std;
 12 
 13 const int maxm = 2000000;
 14 const int maxn = 2007;
 15 
 16 int head[maxm];
 17 
 18 struct node
 19 {
 20     int next,v;
 21 }g[maxm];
 22 
 23 int cnt;
 24 int c[maxn][maxn];
 25 int pos[maxm];
 26 char s[maxn];
 27 int len;
 28 void add(int a,int b,int val)
 29 {
 30     int i,j;
 31     for(i = a;i <= len;i += lowbit(i))
 32     {
 33         for(j = b;j <= len;j += lowbit(j))
 34         c[i][j] += val;
 35     }
 36 }
 37 
 38 int sum(int a,int b)
 39 {
 40     int res = 0;
 41     int i,j;
 42     for(i = a;i > 0;i -= lowbit(i))
 43     {
 44         for(j = b;j > 0;j -= lowbit(j))
 45         res+=c[i][j];
 46     }
 47     return res;
 48 }
 49 void insert(int &u,int key)
 50 {
 51     int i;
 52     for(i = head[u];i != -1;i = g[i].next)
 53     {
 54         int v;
 55         v = g[i].v;
 56         if(v == key)
 57         {
 58             u = i;
 59             return ;
 60         }
 61     }
 62     cnt++;
 63     g[cnt].next = head[u];
 64     g[cnt].v = key;
 65     head[u] = cnt;
 66     u = cnt;
 67     return ;
 68 }
 69 int main()
 70 {
 71     int t;
 72     //freopen("out.txt","w",stdout);
 73     scanf("%d",&t);
 74     while(t--)
 75     {
 76         scanf("%s",s);
 77         len = strlen(s);
 78         cl(c,0);
 79         cl(pos,-1);
 80         cl(head,-1);
 81         int j,i,loc;
 82         loc = 0;
 83         cnt = 0;
 84         loop(0,j,len)
 85         {
 86             loc = 0;
 87             for(i = j;i >= 0;--i)
 88             {
 89                 int key = s[i]-'a';
 90 
 91                 insert(loc,key);
 92 
 93                 if(pos[loc] == -1)
 94                 {
 95                     add(i+1,j+1,1);
 96                     pos[loc] = i+1;
 97                 }
 98                 else if(pos[loc] < (i+1))
 99                 {
100                     add(i+1,j+1,1);
101                     add(pos[loc],j+1,-1);
102                     pos[loc] = i+1;
103                 }
104             }
105         }
106         int m,l,r;
107         scanf("%d",&m);
108         while(m--)
109         {
110             scanf("%d %d",&l,&r);
111             printf("%d\n",sum(l-1,0)+sum(len,r)-sum(l-1,r)-sum(len,0));
112         }
113 
114     }
115     return 0;
116 }
View Code

相关文章:

  • 2021-12-22
  • 2022-02-21
  • 2022-12-23
  • 2021-12-10
  • 2021-09-28
  • 2022-12-23
  • 2021-07-16
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-10-25
  • 2021-10-11
  • 2022-02-15
  • 2021-09-01
  • 2021-09-01
相关资源
相似解决方案