fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4.  
  5. constexpr int N = 1e5 + 1, GC = 36, B = 320;
  6.  
  7. int id[N], gc = 0;
  8.  
  9. struct Group {
  10. int len, sz, BS, BC;
  11.  
  12. struct Node {
  13. int l, r;
  14. ll val;
  15.  
  16. Node() = default;
  17. Node(ll _val) : val(_val) {}
  18.  
  19. inline void assign(int _l, int _r) {
  20. l = _l;
  21. r = _r;
  22. }
  23.  
  24. inline bool operator<(const Node &e) const { return val < e.val; }
  25. } rlist[N];
  26.  
  27. struct Block {
  28. int lo, hi, lb, rb;
  29. ll lz;
  30.  
  31. Block() = default;
  32. Block(int _rb) : rb(_rb) {}
  33.  
  34. inline bool operator<(const Block &b) const { return rb < b.rb; }
  35. } blk[B];
  36.  
  37. Group() = default;
  38.  
  39. inline void init() {
  40. BS = sqrt(sz);
  41. BC = (sz - 1) / BS + 1;
  42. for (int i = 1; i <= BC; ++i) {
  43. blk[i].lo = blk[i - 1].hi + 1;
  44. blk[i].hi = i * BS;
  45. }
  46. blk[BC].hi = sz;
  47. for (int i = 1; i <= BC; ++i) {
  48. blk[i].lb = rlist[blk[i].lo].l;
  49. blk[i].rb = rlist[blk[i].hi].r;
  50. }
  51. }
  52.  
  53. inline void modify(int p, int ql, int qr, int v) {
  54. for (int i = blk[p].lo; i <= blk[p].hi; ++i) {
  55. if (rlist[i].l > qr || rlist[i].r < ql) continue;
  56. rlist[i].val += (ll)(min(rlist[i].r, qr) - max(rlist[i].l, ql) + 1) * v;
  57. }
  58. sort(rlist + blk[p].lo, rlist + blk[p].hi + 1);
  59. }
  60.  
  61. inline int count(int p, bool all, int ql, int qr, int v) {
  62. if (all) return upper_bound(rlist + blk[p].lo, rlist + blk[p].hi + 1, Node((ll)v - blk[p].lz)) - rlist - blk[p].lo;
  63. int res = 0;
  64. for (int i = blk[p].lo; i <= blk[p].hi; ++i) res += (ql <= rlist[i].l && rlist[i].r <= qr && rlist[i].val + blk[p].lz <= v);
  65. return res;
  66. }
  67.  
  68. inline void update(int ql, int qr, int v) {
  69. int i = lower_bound(blk + 1, blk + BC + 1, Block(ql)) - blk;
  70. if (i > BC) return;
  71. if (blk[i].lb <= ql && qr <= blk[i].rb) {
  72. if (blk[i].lb == ql && qr == blk[i].rb) blk[i].lz += (ll)v * len;
  73. else modify(i, ql, qr, v);
  74. return;
  75. }
  76. if (blk[i].lb < ql) {
  77. modify(i, ql, blk[i].rb, v);
  78. ++i;
  79. }
  80. while (i <= BC && blk[i].rb <= qr) blk[i++].lz += (ll)v * len;
  81. if (i > BC) return;
  82. if (blk[i].lb <= qr) modify(i, blk[i].lb, qr, v);
  83. }
  84.  
  85. inline int query(int ql, int qr, int v) {
  86. int i = lower_bound(blk + 1, blk + BC + 1, Block(ql)) - blk;
  87. if (i > BC) return 0;
  88. if (blk[i].lb <= ql && qr <= blk[i].rb) {
  89. if (blk[i].lb == ql && qr == blk[i].rb) return count(i, true, 0, 0, v);
  90. return count(i, false, ql, qr, v);
  91. }
  92. int res = 0;
  93. if (blk[i].lb < ql) {
  94. res += count(i, false, ql, blk[i].rb, v);
  95. ++i;
  96. }
  97. while (i <= BC && blk[i].rb <= qr) res += count(i++, true, 0, 0, v);
  98. if (i > BC) return res;
  99. if (blk[i].lb <= qr) res += count(i, false, blk[i].lb, qr, v);
  100. return res;
  101. }
  102. } grp[GC];
  103.  
  104. void build(int l, int r) {
  105. const int len = r - l + 1;
  106. int &lid = id[len];
  107. if (!lid) {
  108. lid = ++gc;
  109. grp[gc].len = len;
  110. }
  111. grp[lid].rlist[++grp[lid].sz].assign(l, r);
  112. if (l == r) return;
  113. const int mid = l + r >> 1;
  114. build(l, mid);
  115. build(mid + 1, r);
  116. }
  117.  
  118. int main() {
  119. int n, m, op, l, r, a;
  120. scanf("%d %d", &n, &m);
  121. build(1, n);
  122. for (int i = 1; i <= gc; ++i) grp[i].init();
  123. while (m--) {
  124. scanf("%d %d %d %d", &op, &l, &r, &a);
  125. if (op == 1) for (int i = 1; i <= gc; ++i) grp[i].update(l, r, a);
  126. else {
  127. int res = 0;
  128. for (int i = 1; i <= gc; ++i) res += grp[i].query(l, r, a);
  129. printf("%d\n", res);
  130. }
  131. }
  132. }
Success #stdin #stdout 0.01s 7804KB
stdin
3 3
1 2 3 9
2 1 2 1
2 1 3 1
stdout
1
1