Thursday, 19 May 2016

**Chef and Queries ( add a number in to set , delete anumber form set and , finally print sum in the set)

Chef and Queries 


As part of his daily job, Chef has to solve problems involving sets. Till now, Chef has been using inefficient methods to solve his set related problem, wasting a lot of his precious time. He has agreed to pay you a lot of money for solving the following problem for him efficiently.
First, Chef needs to perform Q operations on a set. Each operation is either:
  • 1. Add a number to the set (if this number is NOT already present in the set).
  • 2. Erase a number from the set (if this number exists in the set).
    • 1 ≤ Q ≤ 107
    • 1 ≤ S1, A, B ≤ 109
  • Then, he needs to find the sum of all elements of the set after performing these Q queries. Your job is to find this sum for him quickly.

    Input

    The first line of input contains four integers — QS1ABS1 is the first number in the operations. Aand B are special constants explained later.
    Every operation Si is represented by a single integer. If Si is odd, then it represents the first operation, otherwise the second type, and in both of them the integer you have to add/delete equals [Si / 2], where [] is the greatest integer (or floor) function.
    Si = (A*Si-1 + B) mod 232 when i > 1.
    Note: In this problem, the time limit is very tight. Using built-in data structures, such as set/unordered_set in C++ or TreeSet/HashSet in Java, may lead to a Time Limit Exceed verdict.

    Output

    Output a single line containing a single integer — sum of elements in the set after Q queries.

    Constraints

    Example

    Input:
    5 1 1 1
    
    Output:
    3
    
    
    Input:
    10000000 777777777 777777777 777777777
    
    Output:
    5362358669068782
    

    Explanation:

    The sequence {Si} is 1, 2, 3, 4, 5:
    Operation 1, 1 mod 2 = 1, add number [1 / 2] = 0 to set, sum is 0.
    Operation 2, 2 mod 2 = 0, erase number [2 / 2] = 1 from set, 1 is not in set, so nothing happens, sum is 0.
    Operation 3, 3 mod 2 = 1, add number [3 / 2] = 1 to set, sum is 1.
    Operation 4, 4 mod 2 = 0, erase number [4 / 2] = 2 from set, 2 is not in set, so nothing happens, sum is 1.
    Operation 5, 5 mod 2 = 1, add number [5 / 2] = 2 to set, sum is 3.
    ==================================EDITORIAL====================================

    DIFFICULTY:

    Easy-Medium

    PREREQUISITES:

    Hash-Table

    PROBLEM:

    Given two types of queries:
    1. Add the number to the set of numbers being maintained. 2. Remove the given number from the set if it exists in it.
    The numbers to be inserted/deleted are generated according to the following scheme:
    S = (a*Si1 + b) mod 232,
    where a and b are integers.
    The sum of the numbers finally remaining in the set after all the operations is to be reported.

    EXPLANATION:

    Given the number of operations to be executed, i.e., q=107, it should be clear that the insertions and deletions from the set are to be done in O(1). Use of STL or pre-written libraries in C++/Java can't be used since they will definitely time out because of associated overheads.
    Hash Table Solution One way is to write our own hash table. Editorialist's solution provides a standard implementation of Hash-Table with chaining to handle collision. For chaining, linked list has been used in the given solution. You can read more about it over the internet.
    Bitset Solution A neater and more concise solution is using Bitset. Let's think about the naive solution to this problem first. If we could simply keep an array of length 2321, then direct insert/lookup in the array would have been possible. The the memory constraints don't allow that big an array. However, let us look at the constraints on the number being inserted/deleted into the set. We know they lie between 0 and 2321, i.e., they can be represented by 31 bits. Now, we can use a smart way to index numbers. Let us keep an array of length 226. This is perfectly fine with the memory limits. Now, for a 31 bit integer x, let the first 26 bits indicate the index in the array where x will reside. The rest 5 bits can be encoded in a 32 bit integer since only different 25 possibilities exist. Please read setter's/tester's solutions for this approach.
    There is one more intricacy here: calculating Si. If we use the normal mod operation present in some of the programming languages, the solution will exceed time limit. This is because mod is a complex operation and performing it 107 times will not work. The observation is that we have to take mod 232. If we keep the data type of Sab to be unsigned, in that case, we will not have to use mod operation because the range of unsigned int is 0 to 2321. Thus, if S goes over 232 it will automatically overflow around to greater than 0. In other words, the compiler will perform the mod function implicitly because of the overflow.

    COMPLEXITY:

    O(1) per insert and delete operation.
    =========================================code===============================
    1. #include <cstdio>
    2. #include <iostream>
    3. #include <cmath>
    4. #include <string>
    5. #include <list>
    6. #include <vector>
    7. #include <algorithm>
    8. #include <functional>
    9. #include <utility>
    10. #include <set>
    11. #include <map>
    12. #include <complex>
    13. #include <queue>
    14. #include <stack>
    15. #include <cstdlib>
    16. #include <ctime>
    17. #include <cstring>
    18. #include <string.h>
    19. using namespace std;
    20. typedef unsigned int uint;
    21. typedef long long int64;
    22. typedef unsigned long long uint64;
    23. typedef unsigned short ushort;
    24. typedef unsigned char uchar;
    25. typedef pair<int,int> ipair;
    26. typedef vector<int> VI;
    27. typedef vector<string> VS;
    28. typedef vector<double> VD;
    29. #define SIZE(A) ((int)(A.size()))
    30. #define LENGTH(A) ((int)(A.length()))
    31. #define MP(A,B) make_pair(A,B)
    32. const double pi=acos(-1.0);
    33. const double eps=1e-11;
    34. #define FOR(i,a,b) for(int i=(a);i<(b);++i)
    35. #define REP(i,a) for(int i=0;i<(a);++i)
    36. #define ALL(a) (a).begin(),(a).end()
    37.  
    38. int64 s;
    39. uint w[1<<26];
    40. void add(uint n)
    41. {
    42. uint b=(((uint)1)<<(n&31));// finding which bit is it out or 32 bits
    43. uint m=(n>>5);// index calculation which is least 26 bits
    44. if (!(w[m]&b)) { s+=n; w[m]|=b; }
    45. }
    46. void remove(uint n)
    47. {
    48. uint b=(((uint)1)<<(n&31));// finding which bit is it out or 32 bits
    49. uint m=(n>>5);// index calculation which is least 26 bits
    50. if (w[m]&b) { s-=n; w[m]^=b; }
    51. }
    52. int main()
    53. {
    54.  
    55. std::ios_base::sync_with_stdio(false);
    56. int q;
    57. uint s1,a,b;
    58. cin>>q>>s1>>a>>b;
    59. memset(w,0,sizeof(w));
    60. s=0;
    61. REP(step,q)
    62. {
    63. if (step>0) s1=a*s1+b;
    64. if (s1&1)
    65. {
    66. uint v=s1>>1;
    67. // cout<<"add"<<s1<<" "<<v<<endl;
    68. add(s1/2);
    69. }
    70. else
    71. {
    72. uint v=s1>>1;
    73. // cout<<"remove "<<s1<<" "<< v<<endl;
    74. remove(s1/2);
    75. }
    76. }
    77. cout<<s<<endl;
    78. return 0;
    79. }