HDU 4821 String(2013长春现场赛I题)

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

 

字符串题。

现场使用字符串HASH乱搞的。

枚举开头!

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <map>
  7 #include <set>
  8 #include <vector>
  9 #include <string>
 10 #include <math.h>
 11 using namespace std;
 12 
 13 int HASH;
 14 const int MAXN = 100010;
 15 int now ;
 16 struct HASHMAP
 17 {
 18     int head[10007],next[MAXN],size;
 19     unsigned long long state[MAXN];
 20     int f[MAXN];
 21     void init()
 22     {
 23         size = 0;
 24         for(int i = 0;i < HASH ;i++)
 25             head[i] = -1;
 26         //memset(head,-1,sizeof(head));
 27     }
 28     int insert(unsigned long long val,int _id)
 29     {
 30         int h = val % HASH;
 31         for(int i = head[h];i != -1;i = next[i])
 32         {
 33             if(val == state[i])
 34             {
 35                 int tmp = f[i];
 36                 f[i] = _id;
 37                 return tmp;
 38             }
 39         }
 40         f[size] = _id;
 41         state[size] = val;
 42         next[size] = head[h];
 43         head[h] = size++;
 44         return 0;
 45     }
 46 }H;
 47 
 48 const int SEED = 13331;
 49 unsigned long long P[MAXN];
 50 unsigned long long S[MAXN];
 51 unsigned long long a[MAXN];
 52 char str[MAXN];
 53 
 54 int main()
 55 {
 56     //freopen("in.txt","r",stdin);
 57     //freopen("out.txt","w",stdout);
 58     P[0] = 1;
 59     for(int i = 1;i < MAXN;i++)
 60         P[i] = P[i-1]*SEED;
 61     int M,L;
 62     now = -1;
 63     while(scanf("%d%d",&M,&L) == 2)
 64     {
 65         now --;
 66         scanf("%s",str);
 67         int n = strlen(str);
 68         S[0] = 0;
 69         for(int i = 1;i <= n;i++)
 70             S[i] = S[i-1]*SEED + str[i-1];
 71         int ans = 0;
 72         if(L>= 300)
 73             HASH = 10007;
 74         else
 75             HASH = 107;
 76         for(int st = 1;st <= L;st++)
 77         {
 78             H.init();
 79             int tmp = 1;
 80             int cnt = 0;
 81             for(int i = st; i + L - 1 <= n;i += L)
 82                 a[++cnt] = S[i+L - 1] - S[i-1] * P[L];
 83             /*
 84             for(int i = 1;i <= cnt;i++)
 85                 cout<<a[i]<<" ";
 86             cout<<endl;
 87             */
 88             for(int i = 1;i <= cnt;i++)
 89             {
 90                 int l = H.insert(a[i],i);
 91                 if(i - l >= M)continue;
 92                 ans += max(0, i - M - tmp + 1);
 93                 tmp = max(tmp,l + 1);
 94                 //printf("%d %d\n",tmp,l);
 95             }
 96             ans += max(0,cnt+1 - M - tmp+1);
 97         }
 98         printf("%d\n",ans);
 99     }
100     return 0;
101 }
102 /*
103 1
104 17239715954 17239715954 17417444844 17239715954 
105 1 0
106 2 1
107 3 2
108 2
109 17417444844 17417444845 17595133743 
110 1 0
111 1 0
112 3
113 17595133744 17595147076 17239702622 
114 1 0
115 1 0
116 0
117 */

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值