震惊!某刚学oi的萌新..写分块写炸了
查看原帖
震惊!某刚学oi的萌新..写分块写炸了
109217
天有不测风云楼主2021/3/31 21:52

样例过了,但是全WA

#include <iostream>
#include <cmath>
#include <cstdio>
#define int long long
using namespace std;

long long n, m;
long long a[200005];
long long opt, l, r, k, p;
int id[200005], b[200005], s[200005], len;
//id:所在块 b:块被加和 s:块和,与2357的
//https://www.luogu.com.cn/blog/107232/solution-p2357
//这篇博客一样

inline long long read() {
  long long X = 0; bool flag = 1; char ch = getchar();
  while (ch < '0' || ch > '9') {if (ch == '-') flag = 0; ch = getchar();}
  while (ch >= '0' && ch <= '9') {X = (X << 1) + (X << 3) + ch - '0'; ch = getchar();}
  if (flag) return X;
  return ~ (X - 1);
}

inline void write(int X) {
  if (X < 0) {putchar('-'); X = ~ (X - 1);}
  long long s[50], top = 0;
  while (X) {s[++top] = X % 10; X /= 10;}
  if (!top) s[++top] = 0;
  while (top) putchar(s[top--] + '0');
  putchar('\n');
  return;
}

void add(int l, int r, long long x) { //加法函数
  int sid = id[l], eid = id[r];
  if (sid == eid) {
    for (int i = l; i <= r; i++) a[i] += x, s[sid] += x;
    return;
  }
  for (int i = l; id[i] == sid; i++) a[i] += x, s[sid] += x;
  for (int i = sid + 1; i < eid; i++) b[i] += x, s[i] += len * x;
  for (int i = r; id[i] == eid; i--) a[i] += x, s[eid] += x;
}

void add2(int l, int r, long long x) { //乘法函数,增加量×x时要减一
  int sid = id[l], eid = id[r];
  if (sid == eid) {
    for (int i = l; i <= r; i++) {s[sid] += a[i] * (x - 1); a[i] *= x;}
    return;
  }
  for (int i = l; id[i] == sid; i++) s[sid] += a[i] * (x - 1), a[i] *= x;
  for (int i = sid + 1; i < eid; i++) b[i] += s[i] * (x - 1), s[i] += len * (x - 1);
  for (int i = r; id[i] == eid; i--) s[eid] += a[i] * (x - 1), a[i] *= x;
}

long long query(int l, int r, int p) {
  int sid = id[l], eid = id[r];
  long long ans = 0;
  if (sid == eid) {
    for (int i = l; i <= r; i++) ans += (a[i] + b[sid]) % p;
    return ans;
  }
  for (int i = l; id[i] == sid; i++) ans += (a[i] + b[sid]) % p;
  for (int i = sid + 1; i < eid; i++) ans += s[i] % p;
  for (int i = r; id[i] == eid; i--) ans += (a[i] + b[eid]) % p;
  return ans % p;
}

signed main() {
  n = read(); m = read(); p = read();
  len = sqrt(n);
  for (long long i = 1; i <= n; i++) {
    a[i] = read();
    id[i] = (i - 1) / len + 1;
    s[id[i]] += a[i];
  }
  for (long long i = 1; i <= m; i++) {
    opt = read();
    if (opt == 1) {
      l = read(); r = read(); k = read();
      add2(l, r, k);
    }
    if (opt == 2) {
      l = read(); r = read(); k = read();
      add(l, r, k);
    }
    if (opt == 3) {
      l = read(); r = read();
      write(query(l, r, p) % p);
    }
  }
  return 0;
}

第一组数据:

8 10 571373
5929 7152 8443 6028 8580 5449 8473 4237 
2 4 8 4376
1 2 8 9637
2 2 6 7918
2 5 8 5681
3 2 8
1 1 5 6482
3 1 5
1 5 8 8701
2 5 8 7992
2 5 8 7806

标准输出:

478836
562114

我的输出:

493818
261371
2021/3/31 21:52
加载中...