Title Link: BZOJ-3236 BZOJ-3809
Algorithm one: Mo team
First, the Pure Mo team algorithm is very good to think, is to use the common first key word for the L block, the second key word r of Mo team.
So each time the endpoint moves to add or remove a number, it is easy to maintain the information in a tree-like array. Because of the complexity of LOGN, the complexity is still quite high.
So BZOJ-3236 time limit of 100s, my code ran 98s, insurance over ...
however. The BZOJ-3809 (Slyz god Ben) is not so kind! Direct memory limit 28MB just put my MO team Kacheng mle!. This is a deliberate behavior of the Kaka team! A solemn protest!
Paste a BZOJ-3236 of pure MO Team code:
#include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include < Algorithm> #include <cstring>using namespace std;inline void Read (int &num) {char c; c = GetChar (); while (c &L T ' 0 ' | | C > ' 9 ') c = GetChar (); Num = C-' 0 '; c = GetChar (); while (c >= ' 0 ' && C <= ' 9 ') {num = num * + C-' 0 '; c = GetChar ();}} const int MAXN = 100000 + 5, MAXM = 1000000 + 5;int N, M, Blksize;int A[MAXN], CNT[MAXN], T1[MAXN], t2[maxn];struct query{ int L, R, a, B, Pos, E, Ans1, Ans2; Query () {}query (int x, int y, int p, int q, int o) {L = x; r = y; a = p; b = q; Pos = o;} BOOL operator < (const Query &q) Const {if (E = = Q.E) return R < Q.r;return e < q.e;}} q[maxm];inline bool Cmp (query Q1, query Q2) {return Q1. Pos < Q2. Pos;} inline void Add1 (int x, int Num) {for (int i = x; i <= n; i + = i & i) t1[i] + = Num;} inline int Get1 (int x) {if (x = = 0) return 0;//notice!int ret = 0;for (int i = x; i; i-= i & i) ret + = T1[i];return ret;} inline void Add2 (int x, int Num) {for (int i = x; i <= n; i + = i & i) t2[i] + = Num;} inline int Get2 (int x) {if (x = = 0) return 0;//notice!int ret = 0;for (int i = x; i; i-= i & i) ret + = T2[i];return RET;} inline void Add_num (int x) {if (cnt[x] = = 0) Add2 (x, 1); ++cnt[x]; ADD1 (x, 1);} inline void Del_num (int x) {--cnt[x]; ADD1 (x,-1); if (cnt[x] = = 0) Add2 (x,-1);} void Pull (int f, int. x, int y) {if (x = = y) return;if (f = = 0) if (x < y) for (int i = x; i < y; ++i) del_num (A[i]); else for (int i = x-1; I >= y; i) add_num (A[i]), else if (x < y) for (int i = x + 1; i <= y; ++i) add_num (A[i] ); else for (int i = x; i > y; i) del_num (A[i]);} int main () {Read (n); Read (m); blksize = (int) sqrt ((double) n), for (int i = 1; I <= n; ++i) Read (a[i]); int L, R, A, b;for (int i = 1; I <= m; ++i) { Read (l); Read (R); Read (a); Read (b); Q[i] = Query (L, R, a, b, i); Q[I].E = (L-1)/blksize + 1;} Sort (q + 1, q + M + 1), memset (CNT, 0, sizeof (CNT)), memset (T1, 0, sizeof (T1)); memset (T2, 0, sizeof (T2)); for (int i = Q[1].L; I <= q[1].r; ++i) Add_num (A[i]); Q[1]. Ans1 = Get1 (q[1].b)-Get1 (Q[1].a-1); Q[1]. Ans2 = Get2 (q[1].b)-Get2 (Q[1].a-1); for (int i = 2; I <= m; ++i) {if (Q[I].R < Q[I-1].L) {Pull (0, Q[I-1].L, Q [I].L]; Pull (1, Q[I-1].R, Q[I].R);} else {Pull (1, Q[I-1].R, Q[I].R); Pull (0, Q[I-1].L, Q[I].L);} Q[i]. Ans1 = Get1 (q[i].b)-Get1 (Q[i].a-1); Q[i]. Ans2 = Get2 (q[i].b)-Get2 (q[i].a-1);} Sort (q + 1, q + M + 1, CMP), for (int i = 1; I <= m; ++i) printf ("%d%d\n", Q[i]. ANS1, Q[i]. ANS2); return 0;}
Algorithm two:
[Bzoj 3236] [Ahoi2013] Jobs && [bzoj 3809] "Mo Team | Chunking "