With the Modified Mo team algorithm and the modified team Algorithm
Pre
I learned about the queue algorithm a long time ago.
When the teacher gave a lecture, he mentioned that the online offline ...... However, I have never done any relevant questions,
Today, we have the honor to have a naked question about how to modify the mo team,
Let's share our experience.
Teams with modifications
First of all, we need to know that if a modification operation is added, we certainly cannot simply ask, because this will affect the final result. If you do not want to understand it, please YY yourself ....
Ideas:
So how can we avoid the impact of modification operations?
First, we need to record the inquiry operation and modification operation respectively.
Then
For each query, we first complete the modification operation in this interval.
Set the template of the common MO team
If the modification operation in this query is not useful for the next query, change the modification point back!
Details:
This part of content refers to the question of Luogu zj Yu Neng. I feel this great god's practice is amazing.
1 for (int j = cx [I-1]. tm + 1; j <= cx [I]. tm; j ++) 2 change (gg [j]. pos, gg [j]. val); 3 for (int j = cx [I-1]. tm; j> = cx [I]. tm + 1; j --) 4 change (gg [j]. pos, gg [j]. pre); // pre, not val !!!
First, make it clear that the two loops only execute one
The first cycle is easy to understand, that is, to modify the areas that need to be modified in the current query range.
The second loop is generally executed in the next large loop after the first loop is completed.
First, make it clear that the purpose of this loop is to change the point that has been changed and has no use for this query back.
We record the recent changes in this interval, and the queried array is sorted,
So,
If the last change is useless for this time, the current tm must be <the previous tm!
Code
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <cmath> 5 # include <algorithm> 6 # include <cstdlib> 7 # include <ctime> 8 using namespace std; 9 const int MAXN = 10001; 10 static void read (int & n) 11 {12 char c = '+'; int x = 0; bool flag = 0; 13 while (c <'0' | c> '9') {c = getchar (); if (c = '-') flag = 1 ;} 14 while (c> = '0' & c <= '9') {x = (x <1) + (x <3) + (c-48 ); c = getchar ();} 15 flag = 1? N =-x: n = x; 16} 17 int n, m; 18 int a [MAXN]; 19 struct CX 20 {21 int l, r, id, tm; // tm last change operation 22} cx [MAXN]; 23 int cxnum; 24 struct GG 25 {26 int pos, val, pre; 27} gg [MAXN]; 28 int ggnum; 29 int head [MAXN]; // 30 int where [MAXN]; 31 int base; 32 int vis [MAXN]; // whether there is any change operation 33 int color [MAXN]; 34 int ans = 0; 35 int out [MAXN]; 36 int comp (const CX & a, const CX & B) 37 {38 if (where [. l] = where [B. l]) 39 return A. r <B. r; 40 else 41 return where [. l] <where [B. l]; 42} 43 int calc (int x) 44 {45 if (vis [x]) 46 {47 if (-- color [a [x] = 0) 48 ans --; 49} 50 else 51 {52 if (++ color [a [x] = 1) 53 ans ++; 54} 55 vis [x] =! Vis [x]; 56} 57 void change (int p, int v) 58 {59 if (vis [p]) 60 {61 calc (p ); 62 a [p] = v; 63 calc (p); 64} 65 else 66 a [p] = v; 67} 68 69 int main () 70 {71 read (n); read (m); 72 for (int I = 1; I <= n; I ++) 73 read (a [I]), head [I] = a [I]; 74 base = sqrt (n); 75 for (int I = 1; I <= n; I ++) 76 where [I] = (I-1)/base + 1; 77 for (int I = 1; I <= m; I ++) 78 {79 char c; 80 int x, y; 81 cin> c; 82 read (x); read (y); 83 if (c = 'q') // query 84 {8 5 cxnum ++; 86 cx [cxnum]. l = x; 87 cx [cxnum]. r = y; 88 cx [cxnum]. id = cxnum; 89 cx [cxnum]. tm = ggnum; 90} 91 else 92 {93 ggnum ++; 94 gg [ggnum]. pos = x; 95 gg [ggnum]. val = y; 96 gg [ggnum]. pre = head [x]; 97 head [x] = y; 98} 99} 100 sort (cx + 1, cx + cxnum + 1, comp ); 101 int l = 1, r = 0; 102 for (int I = 1; I <= cxnum; I ++) 103 {104 for (int j = cx [I-1]. tm + 1; j <= cx [I]. tm; j ++) 105 change (gg [j]. pos, gg [j]. val); 106 for (int j = cx [I]. tm + 1; j <= cx [I -1]. tm; j ++) 107 change (gg [j]. pos, gg [j]. pre); // This is pre, not val !!! 108 for (; l <cx [I]. l; l ++) 109 calc (l); 110 for (; l> cx [I]. l; l --) 111 call-1); 112 for (; r <cx [I]. r; r ++) 113 calc (r + 1); 114 for (; r> cx [I]. r, r --) 115 calc (r); 116 out [cx [I]. id] = ans; 117} 118 for (int I = 1; I <= cxnum; I ++) 119 printf ("% d \ n", out [I]); 120 return 0; 121}