https://nanti.jisuanke.com/t/41391
The subject is not hard to figure, more violence, but to be computational complexity, computational complexity does not, will feel that their algorithm time out, not actually.
This topic is all about direct violence to obtain a multiple of the number and every number in less than 1e5, and then update, as previously written E - No Pain No Game segment tree offline processing section ordering the same
Count complexity, harmonic series use twice, once to ask about the number of time to seek multiple, complexity is n * logn so on average about a number of each is about the logn
Because there is a double relationship so that 2 * logn
The complexity of the tree line, and each update is logn, to traverse time
Therefore, the overall complexity is 2 * n * logn * logn, this certainly will not time out.
#include <cstdio> #include <cstring> #include <cstdlib> #include <queue> #include <algorithm> #include <iostream> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e5 + 10; typedef long long ll; vector<int>num[maxn]; int a[maxn], vis[maxn], c[maxn], ans[maxn]; int n, m; struct node { int l, r, id; node(int l=0,int r=0,int id=0):l(l),r(r),id(id){} }ex[maxn]; bool cmp(node a,node b) { return a.r < b.r; } int lowbit(int x) { return x & (-x); } void update(int x,int k) { while (x <= n) { c[x] += k; x += lowbit(x); } } intGetSum ( int X) { int ANS = 0 ; the while (X> 0 ) { ANS + = C [X]; X - = lowbit (X); } return ANS; } int main () { for ( int I = . 1 ; I <MAXN; ++ I) { for ( int J = 2 * I; J <MAXN; = J + I) { NUM [J] .push_back (I); // put factor for each of which the number of playing table, the harmonic series apparent complexity O (nlog n-) } } for (int i = 1; i < maxn; ++i) { for (int j = 2 * i; j < maxn; j += i) { num[i].push_back(j); } } scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= m; i++) { int l, r; scanf("%d%d", &l, &r); ex[i] = node(l, r, i); } memset(vis, -1, sizeof(vis)); sort(ex + 1, ex + 1 + m, cmp); int now = 1; for (int i = 1; i <= n; i++) { int x = a[i]; for (int j = 0; j < num[x].size(); j++) { int y = num[x][j]; if (vis[y] != -1) update(vis[y], 1); } vis[x] = i; while (now <= m && i == ex[now].r) { int res = getsum(ex[now].r) - getsum(ex[now].l - 1); ans[ex[now].id] = res; now++; } } for (int i = 1; i <= m; i++) printf("%d\n", ans[i]); return 0; }