Description
小 B 有一个很大的数 S,长度达到了 N 位;这个数可以看成是一个串,它可能有前导 0,例如00009312345
。小B还有一个素数P。现在,小 B 提出了 M 个询问,每个询问求 S 的一个子串中有多少子串是 P 的倍数(0 也
是P 的倍数)。例如 S为0077时,其子串 007有6个子串:0,0,7,00,07,007;显然0077的子串007有6个子串都是素
数7的倍数。
Input
第一行一个整数:P。第二行一个串:S。第三行一个整数:M。接下来M行,每行两个整数 fr,to,表示对S 的
子串S[fr…to]的一次询问。注意:S的最左端的数字的位置序号为 1;例如S为213567,则S[1]为 2,S[1…3]为 2
13。N,M<=100000,P为素数
Output
输出M行,每行一个整数,第 i行是第 i个询问的答案。
Sample Input
11
121121
3
1 6
1 5
1 4
Sample Output
5
3
2
//第一个询问问的是整个串,满足条件的子串分别有:121121,2112,11,121,121。
HINT
2016.4.19新加数据一组
如果gcd(p,10)=1,显然一个子串是k的倍数当且仅当它的2个后缀mod p余数相同。
当p是2,5的时候可以根据最后一位判断。
这2种情况都可以用莫队。
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (100010)
ll b[MAXN],res[MAXN],belong[MAXN],cnt[MAXN]={};
struct node{
int l,r,id;
friend bool operator<(node a,node b) {
if (belong[a.l] ^ belong[b.l] )
return belong[a.l] < belong[b.l];
return a.r<b.r;
}
}a[MAXN];
char s[MAXN];
ll c[MAXN];
map<ll,int> h;
int main()
{
// freopen("bzoj4542.in","r",stdin);
// freopen(".out","w",stdout);
ll p;cin>>p;
scanf("%s",s+1);
int n=strlen(s+1);
int m=read();
int BS=sqrt(n);
For(i,m){
a[i]=node{read(),read(),i};
}
For(i,n)
belong[i]=(i-1)/BS+1;
int l=1,r=0;
if (p==2||p==5) {
sort(a+1,a+m+1);
ll t=0,ans=0;
For(i,m){
while(l>a[i].l){
l--,t+=((s[l]-'0')%p)==0,ans+=t;
}while(r<a[i].r){
r++;
if (((s[r]-'0')%p)==0) {
t++;
ans+=r-l+1;
}
}while(l<a[i].l){
if (((s[l]-'0')%p)==0) {
ans-=t; t--;
} else {
ans-=t;
}
l++;
}while(r>a[i].r){
if (((s[r]-'0')%p)==0) {
ans-=r-l+1;
t--;
}
r--;
}
res[a[i].id]=ans;
}
}
else {
ll t=0,c10=1;
ForD(i,n) {
t=(t+c10*(s[i]-'0'))%p;
c[i]=t;
c10=(c10*10)%p;
}
c[n+1]=0;
For(i,n+1) h[c[i]]=1;
int pid=0;
for(map<ll,int>::iterator it=h.begin();it!=h.end();it++) {
it->se=++pid;
// cout<<it->se<<endl;
}
// For(i,n) cout<<c[i]<<' '<<h[c[i]]<<endl;
For(i,n+1) c[i]=h[c[i]];
For(i,n) a[i].r++;
sort(a+1,a+m+1);
ll ans=0;
MEM(cnt)
For(i,m){
while(l>a[i].l){
--l;
ans+=cnt[c[l]]++;
}while(r<a[i].r){
++r;
ans+=cnt[c[r]]++;
}while(l<a[i].l){
ans-=--cnt[c[l]];
l++;
}while(r>a[i].r){
ans-=--cnt[c[r]];
r--;
}
res[a[i].id]=ans;
}
}
For(i,m)
printf("%lld\n",res[i]);
return 0;
}