For this kind of interval query problem, if can use the complexity of O (1) to a Manhattan distance of 1 of the other interval, you can directly use the MO team algorithm.
There are two kinds of pointers from the Internet. The first is to establish the minimum spanning tree in Manhattan and then direct DFS to traverse the entire tree to solve it.
There is also a block first, and then the query according to the block number of the first keyword, the right border for the second keyword sort, sort direct direct violence.
The complexity of doing this is n * sqrt (n), and the latter sqrt (n) depends on how the block is divided.
Think about it this way, it's almost like this, because the complexity in the same block is all sqrt (n) levels, even if the interval of the block is crossed because R is ordered, the complexity is not too high.
Block write relatively simple, first shot. As for first build that kind of pointers next time have the opportunity to knock again.
#define _crt_secure_no_deprecate#include <cstdio> #include <cstring> #include <algorithm> #include <cmath>using namespace Std;typedef Long Long ll;const ll MOD = 1e9 + 7;//multiplication Inverse ll ex_gcd (ll A, ll B, LL &x, LL &am P;y) {if (a = = 0 && b = = 0) return-1;if (b = = 0) {x = 1; y = 0; return A;} LL d = ex_gcd (b, A%b, y, x); y-= A/b*x;return D;} ll Get_inv (ll A, ll n = MOD) {ll x, y, d = ex_gcd (A, n, x, y), if (d = = 1) return (x%n + N)% N;else return-1;} const int MAXN = 3e4 + 10; LL NOWCNT[MAXN], A[MAXN], N, m; LL ANS[MAXN], unit_size, inv[maxn];struct q {int L, R, Id;bool operator < (const Q &x) Const {if (L/unit_size = = X.l/unit_size) return R < X.r;return l/unit_size < x.l/unit_size;}}; Q q[maxn];void Gao () {LL Nowl = q[1].l, nowr = Q[1].R; LL nowval = 1, NOWC = 0;for (int i = nowl; I <= nowr; i++) {nowc++; nowcnt[a[i]]++;nowval = (nowval * nowc)% MOD;NOWVA L = (Nowval * inv[nowcnt[a[i]])% MOD;} Ans[q[1].id] = nowval;for (int i = 2; i <= m; i++) {while (Nowl > Q[i].l) {nowl--; nowc++;nowcnt[a[nowl]]++;nowval = (nowval * nowc)% Mod;nowval = (Nowval * inv[now Cnt[a[nowl]])% MOD;} while (Nowr < Q[I].R) {nowr++; nowc++;nowcnt[a[nowr]]++;nowval = (nowval * nowc)% Mod;nowval = (Nowval * inv[nowcnt[a[ NOWR]])% MOD;} while (Nowr > Q[I].R) {nowval = (Nowval * INV[NOWC])% Mod;nowval = (Nowval * NOWCNT[A[NOWR]])% mod;nowcnt[a[nowr]]--; nowr--; nowc--;} while (Nowl < Q[I].L) {Nowval = (Nowval * INV[NOWC])% Mod;nowval = (Nowval * nowcnt[a[nowl]])% mod;nowcnt[a[nowl]]--; nowl++; nowc--;} Ans[q[i].id] = Nowval;}} int main () {for (int i = 1; I <= 30000; i++) inv[i] = GET_INV (i)% mod;int T; scanf ("%d", &t) and while (t--) {memset (n owcnt, 0, sizeof (nowcnt)), scanf ("%d%d", &n, &m), for (int i = 1; I <= n; i++) {scanf ("%d", &a[i]);} for (int i = 1; I <= m; i++) {scanf ("%d%d", &Q[I].L, &Q[I].R); q[i].id = i;} unit_size = (int) sqrt ((double) (n)); if (unit_size <= 0) unit_size = 1;sort (q + 1, q + 1 +m); Gao (); for (int i = 1; I <= m; i++) {printf ("%i64d\n", Ans[i]);}} return 0;}
HDU 5145 NPY and girls-mo team algorithm