题意:给出一个字符串,最长2000,Q个询问,每次询问[L,R]区间内有多少个不同的字串。
可以用后缀自动机做,也可以先把字符串Hash成一个个整数,转化成求一个区间内不同的整数个数。用Trie树Hash超内存了。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned int uint; struct hash_map { const static int mod=2000007; int head[mod],nEle; struct node { uint key1,key2; int key3,pos,pre; node(){} node(uint key1,uint key2,int key3,int pos,int pre) : key1(key1),key2(key2),key3(key3),pos(pos),pre(pre) {} }ele[2000000]; void init() { nEle=0; memset(head,-1,sizeof(head)); } void clear() { for(int i=0;i<nEle;i++) head[ele[i].key1%mod]=-1; nEle=0; } int find(uint key1,uint key2,int len) { int hashcode=key1%mod; for(int i=head[hashcode];i!=-1;i=ele[i].pre) if(ele[i].key1==key1&&ele[i].key2==key2&&ele[i].key3==len) return i; return -1; } int getPos(uint key1,uint key2,int len) { int pos=find(key1,key2,len); if(pos==-1) return -1; return ele[pos].pos; } void updata(uint key1,uint key2,int len,int pos) { int idx=find(key1,key2,len); if(idx==-1) { int tmp=key1%mod; ele[nEle]=node(key1,key2,len,pos,head[tmp]); head[tmp]=nEle++; } else ele[idx].pos=pos; } }hash; int T[2100],LIM; int lowbit(int x) { return x&(-x); } void add(int idx1,int idx2) { //cout<<idx1<<" "<<idx2<<endl; for(int i=idx1;i<=LIM;i+=lowbit(i)) T[i]+=1; for(int i=idx2+1;i<=LIM;i+=lowbit(i)) T[i]-=1; } int query(int idx) { if(idx<=0) return 0; int sum=0; for(int i=idx;i>0;i-=lowbit(i)) sum+=T[i]; return sum; } struct OP { int st,ed,id; OP(){} OP(int st,int ed,int id) : st(st),ed(ed),id(id) {} bool operator<(const OP &B)const { return ed<B.ed; } }op[10005]; const int MaxLen=2100; const int mut1=127; const int mut2=131; int res[10005]; int main() { int t; scanf("%d",&t); hash.init(); while(t--) { char s[MaxLen]; scanf("%s",s+1); int len=(int)strlen(s+1); hash.clear(); LIM=len; for(int i=1;i<=len;i++) T[i]=0; int Q; scanf("%d",&Q); for(int i=0;i<Q;i++) { int st,ed; scanf("%d%d",&st,&ed); op[i]=OP(st,ed,i); } sort(op,op+Q); int ind=0; for(int i=1;i<=len;i++) { uint key1=0,key2=0; for(int j=i;j>=1;j--) { key1=key1*mut1+s[j]; key2=key2*mut2+s[j]; int pos=hash.getPos(key1,key2,i-j+1); if(pos==-1) pos=0; add(pos+1,j); hash.updata(key1,key2,i-j+1,j); } while(ind<Q&&op[ind].ed==i) { res[op[ind].id]=query(op[ind].st); ind++; } } for(int i=0;i<Q;i++) printf("%d\n",res[i]); } return 0; }