Korotkodul

спарсы

Nov 23rd, 2021 (edited)
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.90 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <vector>
  4. #include <set>
  5. #include <string>
  6. #include <algorithm>
  7. using namespace std;
  8. using ll = long long;
  9. void cv(vector <ll> v){
  10. for (auto x: v) cout<<x<<' ';
  11. cout<<'\n';
  12. }
  13.  
  14. ll inf = pow(2, 32);
  15. vector <ll> ar(1);//массив - каждый раз создается по 4-м числам
  16. vector <pair<ll,ll>> qr(1); //запросы - каждый раз создается по 4-м числам
  17.  
  18. struct sct{//отрезок: левая граница включ-но, правая включ-но, min, max
  19. ll l, r, mn, mx;
  20. };
  21.  
  22. void csc(sct f){
  23. cout<<f.l<<'-'<<f.r<<" ";
  24. }
  25.  
  26. vector <vector <sct> > wrk; //это и есть разреж-я таблица
  27.  
  28. vector <sct> power; //вектор для каждой степени двойки
  29. sct sm;//любой отрезок любой длины
  30.  
  31. void make(){//заполнить разреженную таблицу
  32. int lvl = 1;//степень двойки
  33. int l,r;
  34. while (pow(2,lvl) <= ar.size()){//пока 2 в степени lvl влезает в массив ar
  35. vector <sct> last = wrk[wrk.size() - 1];
  36. //заполняем информацию об отрезках длины 2^lvl
  37. //с помощью информации об отрезках длины 2^(lvl-1)
  38. int len = pow(2, lvl);
  39. int hlf = len / 2;
  40. for (int i = 0;i<=ar.size()-len;++i){
  41. l = i;
  42. r = i + len - 1;
  43. sct L = last[l]; //левый отрезок длины 2^(lvl-1)
  44. sct R = last[l+hlf]; // правый длины 2^(lvl-1)
  45. sm = {l, r, min(L.mn, R.mn), max(L.mx, R.mx)};//берём минимум и максимум обоих отрезков
  46. power.push_back(sm);//добавляем информацию о новом отрезке в вектор, который соответствует степени двойки этого отрезка
  47. }
  48. wrk.push_back(power);
  49. //добавляем в разреженную таблицу вектор с информацией по отрезкам длин всех степеней двоек, которые умещаеются в массив ar
  50. power.clear();
  51. //очищаем
  52. lvl++;
  53. //увеличить степень
  54. }
  55. }
  56. int main()
  57. {
  58. ios::sync_with_stdio(0);
  59. cin.tie(0);
  60. cout.tie(0);
  61. ll N,M,A,B;
  62. while (true){
  63. cin>>N>>M>>A>>B;
  64. //cin>>N>>M>>A>>B;
  65. if (N==0 && M==0 && A==0 && B==0) break;
  66. //очистить массив чисел и запросы
  67. ar.clear();//массив чисел
  68. qr.clear();//массив запросов
  69. ll d;
  70. ll d1, d2;
  71. //заполняем массив чисел и массив запросов по условию
  72. for (int i = 1;i<=N+M*2;++i){
  73. if (i <= N){
  74. d = ( ((A % inf) * (i % inf)) % inf + (B % inf) ) % inf;
  75. ar.push_back(d);
  76. }
  77. else{
  78. d1 = ( ((A % inf) * (i % inf)) % inf + (B % inf) ) % inf % N;
  79. d1++;
  80. i++;
  81. d2 = ( ((A % inf) * (i % inf)) % inf + (B % inf) ) % inf % N;
  82. d2++;
  83. qr.push_back({d1, d2});
  84. }
  85. }
  86. //сторим разреж-ю таблицу - начиная с 2^0 - отрезков длины 1
  87. for (int i = 0; i < ar.size();++i){
  88. sm = {i, i, ar[i], ar[i]};
  89. power.push_back(sm);
  90. }
  91. wrk.push_back(power);
  92. power.clear();
  93. make();//создаём разреж-ю таблицу
  94. ll ans;
  95. ll tot = 0;
  96. //отвечаем на каждый запрос из массива запросов
  97. for (auto Q: qr){
  98. int a = min(Q.first, Q.second);
  99. int b = max(Q.first, Q.second);
  100. a--;
  101. b--;
  102. //b-a+1 = длина отрезка-запроса, включая левую и правую границы
  103. int LVL = floor(log(b-a+1) / log(2));//макс-я степень двойки, которая умещается в отрезок-запрос
  104. vector <sct> now = wrk[LVL];//вектор с информацией по всем отрезкам этой степени двойки
  105. sct lft = now[a];//левый отрезок длины 2^LVL
  106. sct rgt = now[b - pow(2,LVL) + 1];//правый отрезок длины 2^LVL
  107. ans = min(lft.mn, rgt.mn);//берём минимум из этих пересекающихся отрезков
  108. tot += ans;//прибавляем ответ
  109. }
  110. cout<<tot<<'\n';
  111. wrk.clear();//очищаем разреженную таблицу
  112. }
  113.  
  114. }
Add Comment
Please, Sign In to add comment