1
0

CodeForces-896C.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using int64 = long long;
  4. struct Node {
  5. int left;
  6. mutable int right;
  7. mutable int64 value;
  8. bool operator<(const Node &other) const { return left < other.left; }
  9. };
  10. set<Node> intervals;
  11. int array_size;
  12. set<Node>::iterator split(int position) {
  13. if (position > array_size) return intervals.end();
  14. auto it = prev(intervals.upper_bound({position, 0, 0}));
  15. if (it->left == position) return it;
  16. int right = it->right;
  17. int64 value = it->value;
  18. it->right = position - 1;
  19. return intervals.insert({position, right, value}).first;
  20. }
  21. void add_range(int left, int right, int64 value) {
  22. auto end = split(right + 1);
  23. for (auto it = split(left); it != end; ++it) it->value += value;
  24. }
  25. void assign_range(int left, int right, int64 value) {
  26. auto end = split(right + 1);
  27. auto begin = split(left);
  28. intervals.erase(begin, end);
  29. intervals.insert({left, right, value});
  30. }
  31. int64 kth(int left, int right, int rank) {
  32. auto end = split(right + 1);
  33. vector<pair<int64, int>> values;
  34. for (auto it = split(left); it != end; ++it) {
  35. values.push_back({it->value, it->right - it->left + 1});
  36. }
  37. sort(values.begin(), values.end());
  38. for (auto [value, count] : values) {
  39. if (rank <= count) return value;
  40. rank -= count;
  41. }
  42. return -1;
  43. }
  44. int64 mod_power(int64 base, int64 exponent, int64 modulus) {
  45. int64 result = 1 % modulus;
  46. base %= modulus;
  47. while (exponent > 0) {
  48. if (exponent & 1) result = result * base % modulus;
  49. base = base * base % modulus;
  50. exponent >>= 1;
  51. }
  52. return result;
  53. }
  54. int64 power_sum(int left, int right, int64 exponent, int64 modulus) {
  55. auto end = split(right + 1);
  56. int64 result = 0;
  57. for (auto it = split(left); it != end; ++it) {
  58. int64 count = it->right - it->left + 1;
  59. result = (result + count % modulus * mod_power(it->value, exponent, modulus)) % modulus;
  60. }
  61. return result;
  62. }
  63. int main() {
  64. ios::sync_with_stdio(false);
  65. cin.tie(nullptr);
  66. int operations;
  67. int64 seed, maximum;
  68. cin >> array_size >> operations >> seed >> maximum;
  69. auto random_value = [&]() {
  70. int64 result = seed;
  71. seed = (seed * 7 + 13) % 1'000'000'007LL;
  72. return result;
  73. };
  74. for (int i = 1; i <= array_size; ++i) {
  75. intervals.insert({i, i, random_value() % maximum + 1});
  76. }
  77. while (operations--) {
  78. int type = random_value() % 4 + 1;
  79. int left = random_value() % array_size + 1;
  80. int right = random_value() % array_size + 1;
  81. if (left > right) swap(left, right);
  82. int64 x;
  83. if (type == 3) x = random_value() % (right - left + 1) + 1;
  84. else x = random_value() % maximum + 1;
  85. if (type == 1) add_range(left, right, x);
  86. else if (type == 2) assign_range(left, right, x);
  87. else if (type == 3) cout << kth(left, right, static_cast<int>(x)) << '\n';
  88. else {
  89. int64 modulus = random_value() % maximum + 1;
  90. cout << power_sum(left, right, x, modulus) << '\n';
  91. }
  92. }
  93. return 0;
  94. }