[ HNOI2016 ] 大數
阿新 • • 發佈:2021-07-07
題目
思路
程式碼
#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; }