分块求助0pts全WA
查看原帖
分块求助0pts全WA
681755
CuteGirlGC楼主2024/10/17 00:26

rt

#include <cmath>
#include <iostream>

using namespace std;
using ll = long long;

const ll kMaxN = 2e5 + 1;

ll n, q, m, a[kMaxN], id[kMaxN], bl[kMaxN], lbl[kMaxN], rbl[kMaxN], atag[kMaxN], len;

void C1(ll x, ll y, ll add) {  // 区间加
  if (id[x] != id[y]) {
    for (ll i = x; i <= rbl[id[x]]; i++) {  // 处理[x, rx]
      a[i] = (a[i] + atag[id[x]] + add) % m;
      bl[id[i]] = (bl[id[i]] + add) % m;
    }
    for (ll i = id[x] + 1; i <= id[y] - 1; i++) {  // 处理整块
      atag[i] = (atag[i] + add) % m;
      bl[i] = (bl[i] + (rbl[i] - lbl[i] + 1) * add % m) % m;
    }
    for (ll i = lbl[id[y]]; i <= y; i++) {  // 处理 [ly, y]
      a[i] = (a[i] + atag[id[x]] + add) % m;
      bl[id[i]] = (bl[id[i]] + add) % m;
    }
  } else {
    for (ll i = x; i <= y; i++) {  // [x, y]
      a[i] = (a[i] + atag[id[x]] + add) % m;
      bl[id[i]] = (bl[id[i]] + add) % m;
    }
  }
}

void C2(ll x, ll y, ll mod) { // 区间乘
  if (id[x] != id[y]) {
    for (ll i = x; i <= rbl[id[x]]; i++) { // 处理散块
      ll j = id[x];
      bl[j] = (bl[j] - a[i] - atag[j] + m * 10) % m; // 减去之前的
      a[i] = (a[i] + atag[j]) % m * mod % m;
      bl[j] = (bl[j] + a[i]) % m; // 加上之后的
    }
    for (ll i = id[x] + 1; i <= id[y] - 1; i++) { // 处理整块
      bl[i] = bl[i] * mod % m;
      atag[i] = atag[i] * mod % m;
    }
    for (ll i = lbl[id[y]]; i <= y; i++) {
      ll j = id[y];
      bl[j] = (bl[j] - a[i] - atag[j] + m * 10) % m;
      a[i] = (a[i] + atag[j]) % m * mod % m;
      bl[j] = (bl[j] + a[i]) % m;
    }
  } else {
    for (ll i = x; i <= y; i++) { // 处理 [x, y]
      ll j = id[x];
      bl[j] = (bl[j] - a[i] - atag[j] + m * 10) % m;
      a[i] = (a[i] + atag[j]) % m * mod % m;
      bl[j] = (bl[j] + a[i]) % m;
    }
  }
}

ll G(ll x, ll y) { // 询问
  ll ans = 0;
  if (id[x] != id[y]) {
    for (ll i = x; i <= rbl[id[x]]; i++) { // 处理整块
      ll j = id[x];
      ans = (ans + a[i] + atag[j]) % m; // 加上每一个的权值
    }
    for (ll i = lbl[id[y]]; i <= y; i++) {
      ll j = id[y];
      ans = (ans + a[i] + atag[j]) % m;
    }
    for (ll i = id[x] + 1; i <= id[y] - 1; i++) { // 处理整块
      ans = (ans + bl[i]) % m;  //直接加
    }
  } else {
    for (ll i = x; i <= y; i++) { // [x, y]
      ll j = id[x];
      ans = (ans + a[i] + atag[j]) % m;
    }
  }
  return ans;
}

int main() {
  cin >> n >> q >> m, len = sqrt(n);
  ll c = (n + len - 1) / len;
  for (ll i = 1, x; i <= n; i++) { // 预处理
    cin >> a[i];
    id[i] = (i + len - 1) / len;
    bl[id[i]] += a[i];
    rbl[id[i]] = i;
    lbl[id[i] + 1] = i + 1;
  }
  lbl[1] = 1;
  for (ll op, x, y, k; q; q--) {
    cin >> op >> x >> y;
    if (op == 2) {
      cin >> k;
      C1(x, y, k);
    } else if (op == 1) {
      cin >> k;
      C2(x, y, k);
    } else {
      cout << G(x, y) << '\n';
    }
  }
  return 0;
}
2024/10/17 00:26
加载中...