The problem is:
Initially, the sequence is empty. There are n queries and 4 types of queries:
- Add(x): add x to the sequence, if there is already x in the sequence, still add x.
- Remove(x): remove x from the sequence 1 times.
- Xor(x): replace all N of the sequence with N xor x.
- Sum(K): find sum of the k smallest elements in the sequence.
- 0 <= x, n, K <= 10^5
For each query sum(x), output the sum of the x smallest elements in the sequence.
Input:
7 Add(4) // A[] = {4} Remove(3) // A[] = {4} Add(2) // A[] = {4, 2} Sum(2) // A[] = {4, 2} => Output: 6 Xor(2) // A[] = {4^2, 2^2} = {6, 0} Sum(1) // A[] = {6, 0} => Output: 0 Sum(2) // A[] = {6, 0} => Output: 6
I solved the problem with the following way:
Use a vector A to hold the sequence of numbers, and an array Count[] where Count[x] is the number of occurrences of x in A. Initially A is empty, and every Count[x] = 0.
- For each Add(x) query, I add x to A, and Count[x] = Count[x]+1
- For each Remove(x) query, if Count[x] = 0 then skip, otherwise, remove x from A and Count[x] = Count[x]-1
- For each Xor(x) query, replace every A[i] with A[i]^x
- For each Sum(x) query, sort A in ascending value, take the sum of the first x numbers
It seems that my way has a complexity of O(n^2), so for n <= 100000 the above algorithm cannot work. Is there a better way to solve this problem? Thanks a lot.
My code can run well in n <= 5000. Here is it:
int Count[100001];
vector<int> A;
void Add(int x) {
A.push_back(x);
Count[x] = Count[x]+1;
}
void Remove(int x) {
if (Count[x] == 0) return;
Count[x] = Count[x]-1;
auto Find = find(A.begin(), A.end(), x);
A.erase(Find);
}
void Xor(int x) {
for (int& i : A)
i = i^x;
}
int Sum(int x) {
int Num = 0, S = 0;
for (int i : A) {
if (Num + 1 > x) return S;
S = S + i; Num = Num + 1;
}
return S;
}