1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include<bits/stdc++.h> using namespace std; #define ull unsigned long long const int maxn=3000; const int maxm=maxn*maxn; const ull base=20090327; int n,m; char str[maxn+5]; ull sm[maxn+5],pw[maxn+5]; int id[maxn+5][maxn+5],tot; unordered_map<ull,int> mp; int lst[maxm+5]; int ans[maxn+5][maxn+5]; inline ull Hash(int l,int r){ return sm[r]-sm[l-1]*pw[r-l+1]; } signed main(){ freopen("substring.in","r",stdin); freopen("substring.out","w",stdout); scanf("%d%d",&n,&m); scanf("%s",str+1); pw[0]=1; for(int i=1;i<=n;i++){ sm[i]=base*sm[i-1]+str[i]; pw[i]=base*pw[i-1]; } for(int k=1;k<=n;k++){ mp.clear(); for(int i=1,j=k;j<=n;i++,j++){ ull tmp=Hash(i,j); if(!mp[tmp]) mp[tmp]=++tot; id[i][j]=mp[tmp]; } } for(int k=1;k<=n;k++){ for(int i=1,j=k;j<=n;i++,j++){ ans[i][j]++; ans[lst[id[i][j]]][j]--; lst[id[i][j]]=i; } } for(int i=n;i>=1;i--) for(int j=i;j<=n;j++) ans[i][j]+=ans[i][j-1]; for(int j=1;j<=n;j++) for(int i=j;i>=1;i--) ans[i][j]+=ans[i+1][j]; int l,r; while(m--){ scanf("%d%d",&l,&r); printf("%d\n",ans[l][r]); } return 0; }
|