我们处理一个前缀或者后缀就变成了区间相同数字的个数了
引用LZX的来说就是 http://blog.csdn.net/lzxzxx/article/details/51197592
/* *********************************************** Author :BPM136 Created Time :2016/4/20 9:48:45 File Name :C.cpp ************************************************ */ #include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<cmath> #include<cstring> #include<iomanip> #include<bitset> #include<queue> #include<ctime> #include<set> #include<utility> #include<vector> #include<functional> #include<numeric> #include<memory> #include<iterator> #define LL long long #define DB double #define LB long double #define UL unsigned long #define ULL unsigned long long #define get(a,i) a&(1<<(i-1)) #define PAU putchar(0) #define ENT putchar(32) #define clr(a,b) memset(a,b,sizeof(a)) #define fo(_i,_a,_b) for(int _i=_a;_i<=_b;_i++) #define fd(_i,_a,_b) for(int _i=_a;_i>=_b;_i--) #define efo(_i,_a) for(int _i=last[_a];_i!=0;_i=e[_i].next) #define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout); #define mkd(x) freopen(#x".in","w",stdout); #define setlargestack(x) int size=x<<20;char *p=(char*)malloc(size)+size;__asm__("movl %0, %%esp\n" :: "r"(p)); #define end system("pause") using namespace std; LL read() { LL f=1,d=0;char s=getchar(); while (s<48||s>57){if (s==45) f=-1;s=getchar();} while (s>=48&&s<=57){d=d*10+s-48;s=getchar();} return f*d; } LL readln() { LL f=1,d=0;char s=getchar(); while (s<48||s>57){if (s==45) f=-1;s=getchar();} while (s>=48&&s<=57){d=d*10+s-48;s=getchar();} while (s!=10) s=getchar(); return f*d; } inline void write(LL x) { if(x==0){putchar(48);return;}if(x<0)putchar(45),x=-x; int len=0,buf[20];while(x)buf[len++]=x%10,x/=10; for(int i=len-1;i>=0;i--)putchar(buf[i]+48);return; } inline void writeln(LL x){write(x);ENT;} #define N 100005 int a[N]; LL MOD,val[N],A[N],hash[N],nm=0; struct question { int l,r,id; int bid; int ans; }Q[N]; int n,m; char s[N]; int sb; bool cmpQ(question a,question b){ if(a.bid!=b.bid)return a.bid<b.bid; if(a.r!=b.r)return a.r<b.r; return a.l<b.l; } bool cmpid(question a,question b){ return a.id<b.id; } void prework(){ A[++n]=0;LL po10=1; fd(i,n,1){ (A[i]=A[i+1]+a[i]*po10)%=MOD; hash[++nm]=A[i]; (po10*=10)%=MOD; } sort(hash+1,hash+nm+1); fo(i,1,n){ A[i]=lower_bound(hash+1,hash+nm+1,A[i])-hash; } sort(Q+1,Q+m+1,cmpQ); } void work(){ int l=1,r=0,anss=0; fo(i,1,m){ while(r<Q[i].r)anss+=val[A[++r]]++; while(r>Q[i].r)anss-=--val[A[r--]]; while(l>Q[i].l)anss+=val[A[--l]]++; while(l<Q[i].l)anss-=--val[A[l++]]; Q[i].ans=anss; } sort(Q+1,Q+m+1,cmpid); } int main() { // file(C); MOD=read(); scanf("%s",s+1); n=strlen(s+1); fo(i,1,n)a[i]=s[i]-'0'; m=read(); sb=sqrt(n); fo(i,1,m){ Q[i].l=read(),Q[i].r=read();Q[i].r++; Q[i].id=i; Q[i].bid=(Q[i].l-1)/sb+1; } prework(); #define DEBUG look // fo(i,1,m)cout<<Q[i].l<<' '<<Q[i].r<<endl; work(); fo(i,1,m){ cout<<Q[i].ans<<endl; } return 0; }