萌新调了很久,14 pts,求调
查看原帖
萌新调了很久,14 pts,求调
363006
wangyibo201026楼主2023/1/13 13:32

代码:

#include <bits/stdc++.h>

#define int long long
#define endl '\n';

using namespace std;

const int N = 1e6 + 5;

int n, m, bl = 1010;
int a[N], pos[N], st[5005], ed[5005];

struct Ask{
  int op, l, r, x, ans;
}b[N];

int l, r, tag, maxi;
int fa[N], rt[N], size[N], v[N];

int find(int x){
  if(fa[x] == x){
    return x;
  }
  return fa[x] = find(fa[x]);
}

void unionn(int x, int y){
  if(rt[y]){
    fa[rt[x]] = rt[y];
  }
  else{
    rt[y] = rt[x];
    v[rt[y]] = y;
  }
  size[y] += size[x];
  rt[x] = size[x] = 0;
}

void build(){
  maxi = 0;
  for(int i = l; i <= r; i++){
    if(!rt[a[i]]){
      rt[a[i]] = i;
      fa[i] = i;
      v[i] = a[i];
    }
    else{
      fa[i] = rt[a[i]];
    }
    maxi = max(maxi, a[i]);
    size[a[i]]++;
  }
}

void update1(int x){
  if(x * 2 < maxi - tag){
    for(int i = 1 + tag; i <= x + tag; i++){
      if(rt[i]){
        unionn(i, i + x);
      }
    }
    tag += x;
  }
  else{
    for(int i = x + 1 + tag; i <= maxi; i++){
      if(rt[i]){
        unionn(i, i - x);
      }
    }
    maxi = min(maxi, x + tag);
  }
}

void update2(int L, int R, int x){
  if(L > R){
    return ;
  }
  else{
    for(int i = l; i <= r; i++){
      a[i] = v[find(i)];
      rt[a[i]] = size[a[i]] = 0;
      a[i] -= tag;
    }
    for(int i = l; i <= r; i++){
      fa[i] = 0;
    }
    tag = 0;
    for(int i = L; i <= R; i++){
      a[i] -= (a[i] > x ? x : 0);
    }
    build();
  }
}

int query1(int x){
  return (x + tag > 500000 ? 0 : size[x + tag]);
}

int query2(int L, int R, int x){
  if(L > R){
    return 0;
  }
  int cnt = 0;
  for(int i = L; i <= R; i++){
    cnt += (v[find(i)] - tag == x);
  }
  return cnt;
}

void Solve(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for(int i = 1; i <= n; i++){
    cin >> a[i];
    pos[i] = (i - 1) / bl + 1;
  }
  for(int i = 1; i <= m; i++){
    cin >> b[i].op >> b[i].l >> b[i].r >> b[i].x;
  }
  int now_bl = pos[n];
  for(int i = 1; i <= now_bl; i++){
    st[i] = (i - 1) * bl + 1;
    ed[i] = i * bl;
  }
  ed[now_bl] = n;
  for(int i = 1; i <= now_bl; i++){
    l = st[i], r = ed[i];
    build();
    for(int j = 1; j <= m; j++){
      if(l > b[j].r || r < b[j].l){
        continue;
      }
      if(b[j].op == 1){
        if(b[j].l <= l && r <= b[j].r){
          update1(b[j].x);
        }
        else{
          update2(max(l, b[j].l), min(r, b[j].r), b[j].x);
        }
      }
      else{
        if(b[j].l <= l && r <= b[j].r){
          b[j].ans += query1(b[j].x);
        }
        else{
          b[j].ans += query2(max(l, b[j].l), min(r, b[j].r), b[j].x);
        }
      }
    }
  }
  for(int i = 1; i <= m; i++){
    if(b[i].op == 2){
      cout << b[i].ans << '\n';
    }
  }
}

signed main(){
  Solve();
  return 0;
}
2023/1/13 13:32
加载中...