0分WA求助
查看原帖
0分WA求助
565669
Marrelia楼主2024/1/4 13:17

样例可以过

#include <cstdio>

const int N = 4e5 + 9;

#define int long long

int sum[N], tag1[N], tag2[N];

bool isTag2[N];

int n, q, m;

void pushup(int id) {
  sum[id] = (sum[id << 1] + sum[id << 1 | 1]) % m;
}

void build(int id, int L, int R) {
  if (L == R) {
    scanf("%lld", &sum[id]);
    sum[id] %= m;
    return;
  }
  
  int mid = (L + R) >> 1;
  build(id << 1, L, mid);
  build(id << 1 | 1, mid + 1, R);
  
  pushup(id);
}

void initTag2(int id) {
  if (!isTag2[id])
    tag2[id] = 1;
}

void changeTag2(int id1, int id2, int L, int R) {
  // id1的tag2修改id2
  sum[id2] = (1LL * sum[id2] * tag2[id1]) % m;
  tag2[id2] = (1LL * tag2[id2] * tag2[id1]) % m;
  isTag2[id2] = true;
}

void changeTag1(int id1, int id2, int L, int R) {
  // id1的tag1修改id2
  sum[id2] = (long long)(sum[id2] + ((R - L + 1) % m) * (tag1[id1])) % m;
  tag1[id2] = (tag1[id1] + tag1[id2]) % m;
}

void pushdown(int id, int L, int R) {
  initTag2(id << 1), initTag2(id << 1 | 1);
  
  int mid = (L + R) >> 1;
  if (isTag2[id]) {
    changeTag2(id, id << 1, L, mid);
    changeTag2(id, id << 1 | 1, mid + 1, R);
  }
  changeTag1(id, id << 1, L, mid);
  changeTag1(id, id << 1 | 1, mid + 1, R);
  
  isTag2[id] = false;
  tag1[id] = 0;
}

int query(int id, int L, int R, int qL, int qR) {
  if (L == qL && R == qR) {
    return sum[id];
  }
  
  pushdown(id, L, R);
  int mid = (L + R) >> 1;
  if (qR <= mid)
    return query(id << 1, L, mid, qL, qR);
  else if (qL > mid)
    return query(id << 1 | 1, mid + 1, R, qL, qR);
  else
    return (query(id << 1, L, mid, qL, mid) + query(id << 1 | 1, mid + 1, R, mid + 1, qR)) % m;
}

void add(int id, int L, int R, int qL, int qR, int k) {
  
  if (L == qL && R == qR) {
    sum[id] = (sum[id] + ((R - L + 1) * k) % m) % m;
    tag1[id] = (tag1[id] + k) % m;
    return;
  }
  
  pushdown(id, L, R);
  
  int mid = (L + R) >> 1;
  if (qR <= mid)
    add(id << 1, L, mid, qL, qR, k);
  else if (qL > mid)
    add(id << 1 | 1, mid + 1, R, qL, qR, k);
  else {
    add(id << 1, L, mid, qL, mid, k);
    add(id << 1 | 1, mid + 1, R, mid + 1, qR, k);
  }
  pushup(id);
}

void mult(int id, int L, int R, int qL, int qR, int k) {
  // puts("1");
  if (L == qL && R == qR) {
    initTag2(id);
    
    // printf("%d\n", tag1[id]);
    sum[id] = (1LL * sum[id] * k) % m;
    if (tag1[id] == 0) {
      // puts("11111111----1");
      tag2[id] = (1LL * tag2[id] * k) % m;
      isTag2[id] = true;
    } else {
      tag1[id] = (1LL * tag1[id] * k) % m;
    }
    return;
  }
  
  pushdown(id, L, R);
  
  int mid = (L + R) >> 1;
  if (qR <= mid)
    mult(id << 1, L, mid, qL, qR, k);
  else if (qL > mid)
    mult(id << 1 | 1, mid + 1, R, qL, qR, k);
  else {
    mult(id << 1, L, mid, qL, mid, k);
    mult(id << 1 | 1, mid + 1, R, mid + 1, qR, k);
  }
  pushup(id);
}

signed main() {
  scanf("%lld%lld%lld", &n, &q, &m);
  build(1, 1, n);
  while (q--) {
    int opt, x, y, k;
    scanf("%lld", &opt);
    
    if (opt < 1 || opt > 3) {
      ++q;
      continue;
    }
    
    scanf("%lld%lld", &x, &y);
    
    if (opt != 3) {
      scanf("%lld", &k);
      k %= m;
    }
    
    if (opt == 2) {
      add(1, 1, n, x, y, k);
    } else if (opt == 1) {
      // puts("1");
      mult(1, 1, n, x, y, k);
    } else if (opt == 3) {
      printf("%lld\n", query(1, 1, n, x, y));
    }
  }
  return 0;
}
2024/1/4 13:17
加载中...