fork download
  1. #include <iostream>
  2. #include <deque>
  3.  
  4. using namespace std;
  5.  
  6. template <class T>
  7. struct Operation
  8. {
  9. virtual ~Operation() {}
  10.  
  11. virtual Operation * Clone() const = 0;
  12.  
  13. virtual T ApplyDirect (T value) const = 0;
  14. virtual T ApplyInverse(T value) const = 0;
  15. };
  16.  
  17. template <class T>
  18. struct Add : Operation<T>
  19. {
  20. T amount;
  21.  
  22. Add(T amount_) : amount(amount_) {}
  23.  
  24. Add * Clone() const { return new Add(amount); }
  25.  
  26. T ApplyDirect (T value) const { return value + amount; }
  27. T ApplyInverse(T value) const { return value - amount; }
  28. };
  29.  
  30. template <class T>
  31. struct Mul : Operation<T>
  32. {
  33. T amount;
  34.  
  35. Mul(T amount_) : amount(amount_) {}
  36.  
  37. Mul * Clone() const { return new Mul(amount); }
  38.  
  39. T ApplyDirect (T value) const { return value * amount; }
  40. T ApplyInverse(T value) const { return value / amount; }
  41. };
  42.  
  43. template <class T, unsigned N>
  44. class MassiveValArray
  45. {
  46. deque<T> data;
  47.  
  48. deque<unsigned> changedElements;
  49. deque<Operation<T>*> operations;
  50.  
  51. void makeSomeCalculations()
  52. {
  53. if (changedElements.empty()) return;
  54.  
  55. static const unsigned elementsChangedPerCall = 3;
  56.  
  57. for (unsigned i = 0; i < elementsChangedPerCall; ++ i)
  58. {
  59. unsigned index = changedElements[0] + i;
  60.  
  61. if (index >= N) break;
  62.  
  63. data[index] = operations[0]->ApplyDirect(data[index]);
  64. }
  65.  
  66. changedElements[0] += elementsChangedPerCall;
  67.  
  68. if (changedElements[0] >= N)
  69. {
  70. changedElements.pop_front();
  71.  
  72. delete operations[0];
  73. operations.pop_front();
  74. }
  75. }
  76.  
  77. public:
  78.  
  79. MassiveValArray() : data(N) {}
  80. MassiveValArray(T initialValue) : data(N, initialValue) {}
  81.  
  82. ~MassiveValArray() { for (unsigned i = 0; i < operations.size(); ++ i) delete operations[i]; }
  83.  
  84. T Get(unsigned index)
  85. {
  86. if (operations.empty()) return data[index];
  87.  
  88. makeSomeCalculations();
  89.  
  90. T ret = data[index];
  91.  
  92. for (unsigned i = 0, size = operations.size(); i < size; ++ i)
  93. if (changedElements[i] <= index)
  94. ret = operations[i]->ApplyDirect(ret);
  95.  
  96. return ret;
  97. }
  98.  
  99. void Set(unsigned index, T value)
  100. {
  101. if (operations.empty()) { data[index] = value; return; }
  102.  
  103. makeSomeCalculations();
  104.  
  105. for (unsigned i = operations.size() - 1; i + 1 > 0; -- i)
  106. if (changedElements[i] <= index)
  107. value = operations[i]->ApplyInverse(value);
  108.  
  109. data[index] = value;
  110. }
  111.  
  112. void ApplyToAll(const Operation<T> & op)
  113. {
  114. operations.push_back(op.Clone());
  115. changedElements.push_back(0);
  116.  
  117. makeSomeCalculations();
  118. }
  119.  
  120. ostream & Print()
  121. {
  122. for (unsigned i = 0; i < N; ++ i)
  123. cout << Get(i) << " ";
  124.  
  125. return cout << endl;
  126. }
  127.  
  128. ostream & PrintOpInfo() const
  129. {
  130. unsigned opCount = operations.size();
  131.  
  132. cout << "stacked ops : " << opCount << endl;
  133.  
  134. if (opCount > 0)
  135. cout << "front op completion : "
  136. << changedElements[0] * 100 / N
  137. << "%" << endl;
  138.  
  139. return cout;
  140. }
  141. };
  142.  
  143. int main()
  144. {
  145. MassiveValArray<double, 35> arr(1);
  146.  
  147. arr.Print();
  148.  
  149. arr.ApplyToAll(Mul<double>(2.0)); arr.ApplyToAll(Add<double>(1.0));
  150. arr.ApplyToAll(Mul<double>(2.0)); arr.ApplyToAll(Add<double>(3.0));
  151.  
  152. arr.Set(0, 0.0); arr.Set(1, 1.0); arr.Set(2, 2.0); arr.Set(3, 3.0); arr.Set(4, 4.0); arr.Set(5, 5.0);
  153.  
  154. cout << "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n" << endl;
  155.  
  156. arr.PrintOpInfo();
  157.  
  158. cout << "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n" << endl;
  159.  
  160. arr.Print() << endl; arr.PrintOpInfo();
  161.  
  162. cout << "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n" << endl;
  163.  
  164. arr.Print() << endl; arr.PrintOpInfo();
  165. }
Success #stdin #stdout 0.01s 2828KB
stdin
Standard input is empty
stdout
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

stacked ops : 4
front op completion : 85%

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

0 1 2 3 4 5 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 

stacked ops : 1
front op completion : 77%

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

0 1 2 3 4 5 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 

stacked ops : 0