# 【bzoj4542】[Hnoi2016]大数 莫队算法

N,M<=100000，P为素数

11
121121
3
1 6
1 5
1 4

5
3
2

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
typedef long long ll;
ll p;
char str[N];
{
ll s1[N] , s2[N];
void solve()
{
int n , m , i , l , r;
scanf("%s%d" , str + 1 , &m) , n = strlen(str + 1);
for(i = 1 ; i <= n ; i ++ )
{
s1[i] = s1[i - 1] , s2[i] = s2[i - 1];
if((str[i] - '0') % p == 0) s1[i] ++ , s2[i] += i;
}
while(m -- )
{
scanf("%d%d" , &l , &r);
printf("%lld\n" , s2[r] - s2[l - 1] - (l - 1) * (s1[r] - s1[l - 1]));
}
}
}
{
struct data
{
int l , r , bl , id;
bool operator<(const data &a)const {return bl == a.bl ? r < a.r : bl < a.bl;}
}q[N];
int a[N] , mp[N];
ll b[N] , v[N] , ans[N];
void solve()
{
int n , m , i , si , lp = 1 , rp = 0;
ll t = 1 , now = 0;
scanf("%s%d" , str + 1 , &m) , n = strlen(str + 1) , si = (int)sqrt(n);
for(i = n ; i ; i -- , t = t * 10 % p) v[i] = b[i] = (b[i + 1] + (str[i] - '0') * t) % p;
v[n + 1] = 0 , sort(v + 1 , v + n + 2);
for(i = 1 ; i <= n + 1 ; i ++ ) a[i] = lower_bound(v + 1 , v + n + 2 , b[i]) - v;
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &q[i].l , &q[i].r) , q[i].r ++ , q[i].bl = (q[i].l - 1) / si , q[i].id = i;
sort(q + 1 , q + m + 1);
for(i = 1 ; i <= m ; i ++ )
{
while(lp > q[i].l) now += mp[a[--lp]] , mp[a[lp]] ++ ;
while(rp < q[i].r) now += mp[a[++rp]] , mp[a[rp]] ++ ;
while(lp < q[i].l) mp[a[lp]] -- , now -= mp[a[lp++]];
while(rp > q[i].r) mp[a[rp]] -- , now -= mp[a[rp--]];
ans[q[i].id] = now;
}
for(i = 1 ; i <= m ; i ++ ) printf("%lld\n" , ans[i]);
}
}
int main()
{
scanf("%lld" , &p);
if(p == 2 || p == 5) task1::solve();