关于分块(玄关求助
  • 板块学术版
  • 楼主Epitome
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/8/3 23:04
  • 上次更新2024/8/4 09:33:21
查看原帖
关于分块(玄关求助
994729
Epitome楼主2024/8/3 23:04

块长会对答案有影响吗,如果没有还请帮帮蒟蒻调一下 P3373 分块做法,块长 300 就 WA,500 就 T。

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 2e5 + 5, B = 500;

ll n, m, a[N], fix[N], b[N][2], Mod;

inline int get(int x){
  return (x - 1) / B + 1;
}

void push_down(int id){
  for(int i = id * B; i < (id + 1) * B; ++i)
    a[i] = (a[i] * b[id][0] + b[id][1]) % Mod;
  b[id][0] = 1, b[id][1] = 0;
}

void update_add(int l, int r, int k){
  k %= Mod;
  if(get(l) == get(r)){
    push_down(get(l));
    for(int i = l; i <= r; ++i){
      a[i] += k, fix[get(i)] += k;
      a[i] %= Mod, fix[get(i)] %= Mod;
    }
  }else{
    int i = l, j = r;
    push_down(get(i));
    while(get(i) == get(l)){
      a[i] += k, fix[get(i)] += k;
      a[i] %= Mod, fix[get(i)] %= Mod;
      ++i;
    }
    push_down(get(j));
    while(get(j) == get(r)){
      a[j] += k, fix[get(j)] += k;
      a[j] %= Mod, fix[get(j)] %= Mod;
      --j;
    }
    for(int p = get(i); p <= get(j); ++p){
      b[p][0] += k, fix[p] += k * B;
      b[p][0] %= Mod, fix[p] %= Mod; 
    }
  }
}

void update_mul(int l, int r, int k){
  k %= Mod;
  if(get(l) == get(r)){
    push_down(get(l));
    for(int i = l; i <= r; ++i){
      a[i] *= k, fix[get(i)] += (k - 1) * a[i];
      a[i] %= Mod, fix[get(i)] %= Mod;
    }
  }else{
    int i = l, j = r;
    push_down(get(i));
    while(get(i) == get(l)){
      a[i] *= k, fix[get(i)] += (k - 1) * a[i];
      a[i] %= Mod, fix[get(i)] %= Mod;
      ++i;
    }
    push_down(get(j));
    while(get(j) == get(r)){
      a[j] *= k, fix[get(j)] += (k - 1) * a[j];
      a[j] %= Mod, fix[get(j)] %= Mod;
      --j;
    }
    for(int p = get(i); p <= get(j); ++p){
      b[p][1] *= k, fix[p] *= k; 
      b[p][1] %= Mod, fix[p] %= Mod;
    }
  }
}

int query(int l, int r){
  ll ret = 0;
  if(get(l) == get(r)){
    for(int i = l; i <= r; ++i){
      ret = (ret + a[i] * b[get(i)][0] + b[get(i)][1]) % Mod;
    }
  }else{
    int i = l, j = r;
    while(get(i) == get(l)){
      ret = (ret + a[i] * b[get(i)][0] + b[get(i)][1]) % Mod;
      ++i;
    }
    while(get(j) == get(r)){
      ret = (ret + a[j] * b[get(j)][0] + b[get(j)][1]) % Mod;
      --j;
    }
    for(int p = get(i); p <= get(j); ++p){
      ret = (ret + fix[p]) % Mod;
    }
  }
  return ret;
}

int main(){
  ios :: sync_with_stdio(0), cin.tie(0);
  cin >> n >> Mod;
  for(int i = 1; i <= n; ++i){
    cin >> a[i];
    a[i] %= Mod;
    fix[get(i)] = (fix[get(i)] + a[i]) % Mod;
    b[i][0] = 1;
  }
  cin >> m;
  while(m--){
    int op, l, r, k;
    cin >> op;
    if(op == 1){
      cin >> l >> r >> k;
      update_mul(l, r, k);
    }else if(op == 2){
      cin >> l >> r >> k;
      update_add(l, r, k);
    }else{
      cin >> l >> r;
      cout << query(l, r) % Mod << '\n';
    }
  }
  return 0;
}
2024/8/3 23:04
加载中...