This problem uses a hash table to deal with conflicts, give you a hash table label size H from 0 to h-1, as hash [0] ~ Hash [h-1]
There are two operations:
1: "+ id ha": inserts an element with hash value H and ID into the hash table. If hash [Ha] is empty, insert it directly, if hash [Ha] is occupied, insert a number m at (HA + M) % H. If it is not empty, insert at (HA + 2 * m) % H until a position is found. (The question cannot be inserted.) If the last Insertion Location is (HA + I * m) % H, it will take I points.
2. "-ID": indicates to delete an element labeled as ID (ensure that the ID is in the hash table ).
Now we have given n operations and asked how much it will cost.
Idea: we can observe that if there is a conflict in every position, its next position is determined. In fact, they constitute a loop together, then we can turn this loop into a chain and place it in the line segment tree. The line segment tree implements two operations: one is to fill a position (assigned to 1) or clear (with a value of 0). Second, return the position in the online segment tree with the leftmost left position in the interval. If not, return-1. because a hash table may have multiple chains, we must first maintain the number of left and right vertices in the number of online segments of each chain on the chain, there are also locations in the online segment tree at each location, which can be completed in Preprocessing. In this way, for operation 2, locate the position inserted before the ID (implemented by map ), clear the location. For operation 1, set the hash value to ha, and find the corresponding location Po in the HA online segment tree, and the left and right vertex L between the HA segment, r: returns the leftmost free position of [Po, R]. If no, returns the leftmost free position of [L, po. If you set the last insert position to PP, the ID is inserted to PP (in the online segment tree ). The rest is the price. With PP, Po, L, R, this is a good request. For specific implementation, see the code.
# Include <iostream> # include <string. h> # include <stdio. h> # include <map> # define maxn 200010 # define mid (T [p]. L + T [p]. r)> 1) # define ls (P <1) # define RS (LS | 1) Using namespace STD; Map <int, int> MP; struct tree {int L, R; int po;} t [maxn <1]; void pushup (INT p) {If (T [ls]. po! =-1) T [p]. Po = T [ls]. Po; else if (T [RS]. Po! =-1) T [p]. po = T [RS]. po; else t [p]. po =-1;} void build (int p, int L, int R) {T [p]. L = L, t [p]. R = r; If (L = r) {T [p]. po = L; return;} build (LS, L, mid); Build (RS, Mid + 1, R); pushup (p);} void change (int p, int X, int Val) {If (T [p]. L = T [p]. r) {If (VAL) {T [p]. po =-1;} else {T [p]. po = T [p]. l;} return;} If (x> mid) Change (RS, X, Val); else change (LS, X, Val); pushup (p );} int getpo (int p, int L, int R) {If (T [p]. L = L & T [p]. R = r ){ Return T [p]. po;} If (r <= mid) return getpo (LS, L, R); else if (L> mid) return getpo (RS, L, R ); else {int LL = getpo (LS, L, mid), RR = getpo (RS, Mid + 1, R); If (ll! =-1) return ll; If (RR! =-1) return RR; Return-1 ;}} int po [maxn], vis [maxn], LR [maxn] [2]; void Init (int n, int m) {int I, TMP, num = 1, sum = 1; LR [0] [0] = LR [0] [1] = 0; for (I = 0; I <n; I ++) {If (vis [I]) continue; TMP = I; LR [Sum] [0] = num; while (! Vis [TMP]) {po [TMP] = num ++; vis [TMP] = sum; TMP = (TMP + M) % N ;} LR [Sum] [1] = num-1; sum ++;} int main () {freopen ("dd.txt", "r", stdin); int H, m, n, a, B; scanf ("% d", & H, & M, & N); Init (H, m); Build (1,1, h); char STR [2]; long ans = 0; while (n --) {scanf ("% s", STR ); if (STR [0] = '+') {scanf ("% d", & A, & B); int num = vis [B]; // B in the num interval int L = LR [num] [0], r = LR [num] [1]; int P = po [B]; int pp = getpo (1, P, R); If (PP! =-1) {ans + = (PP-P);} else {ans + = r-p; pp = getpo (1, L, P ); ans + = PP-L + 1;} change (1, PP, 1); MP. insert (make_pair (A, pp);} else {scanf ("% d", & A); int P = MP. find (a)-> second; Change (1, P, 0); MP. erase (a) ;}} printf ("% i64d \ n", ANS); Return 0 ;}