[ HNOI2016 ] 大数
题目
思路
代码
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cmath>
#define int long long
using namespace std;
const int N = 200010;
int n, P, m, f[N], s[N], id[N], res[N];
struct QUERY { int l, r, id; } Q[N];
bool operator<(QUERY a, QUERY b) {
if (id[a.l] != id[b.l]) return a.l < b.l;
return id[a.l] & 1 ? a.r < b.r : a.r > b.r;
}
char str[N];
vector<int> nums;
void init() {
n = strlen(str + 1);
int B = sqrt(n), S = (n + B - 1) / B, pow = 1;
for (int i = n; i >= 1; i--) {
s[i] = ((str[i] - '0') * pow % P + s[i + 1]) % P;
nums.push_back(s[i]);
pow = pow * 10 % P, id[i] = (i + B - 1) / B;
}
nums.push_back(0);
sort(nums.begin(), nums.end());
nums.erase(unique(nums.begin(), nums.end()), nums.end());
for (int i = 1; i <= n + 1; i++)
s[i] = lower_bound(nums.begin(), nums.end(), s[i]) - nums.begin();
}
int A[N], B[N];
void work1() {
for (int i = 1; i <= n; i++) {
A[i] = A[i - 1] + (!((str[i] - '0') % P));
B[i] = B[i - 1] + (!((str[i] - '0') % P)) * i;
}
for (int i = 1, l, r; i <= m && cin >> l >> r; i++)
cout << (B[r] - B[l - 1] - (A[r] - A[l - 1]) * (l - 1)) << endl;
}
int ans = 0;
void del(int x) { f[x]--, ans -= f[x]; }
void upd(int x) { ans += f[x], f[x]++; }
void work2() {
for (int i = 1; i <= m; i++)
cin >> Q[i].l >> Q[i].r, Q[i].r++, Q[i].id = i;
sort(Q + 1, Q + m + 1);
int l = 1, r = 0;
for (int i = 1; i <= m; i++) {
while (l < Q[i].l) del(s[l++]);
while (l > Q[i].l) upd(s[--l]);
while (r < Q[i].r) upd(s[++r]);
while (r > Q[i].r) del(s[r--]);
res[Q[i].id] = ans;
}
for (int i = 1; i <= m; i++) cout << res[i] << endl;
}
signed main() {
cin >> P >> str + 1 >> m;
init(), (P == 2 || P == 5) ? work1() : work2();
return 0;
}