求调数据结构码力题(悬3关)
  • 板块灌水区
  • 楼主mm1214
  • 当前回复6
  • 已保存回复6
  • 发布时间2024/7/31 18:09
  • 上次更新2024/7/31 19:45:42
查看原帖
求调数据结构码力题(悬3关)
774258
mm1214楼主2024/7/31 18:09

U449818,看线段树似乎很难写,所以用了分块

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#define int long long
#define pii pair<int , int>
#define pb emplace_back
#define mkp make_pair
#define fi first
#define se second
#define ls (rt << 1)
#define rs (rt << 1 | 1)
#define mid (l + r >> 1)
using namespace std;
using namespace __gnu_pbds;
constexpr int N = 100005 , inf = 2e12;
int a[N] , B , L[N] , R[N] , bel[N] , sum[N] , mx[N] , mi[N] , adtag[N];
void calc(int i , int l , int r) {
    if (l > r) return;
    sum[i] = 0 , mx[i] = -inf , mi[i] = inf;
    for (int j = l; j <= r; j++) {
        a[j] += adtag[i];
        bel[j] = i; mx[i] = max(mx[i] , a[j]); mi[i] = min(mi[i] , a[j]); sum[i] += a[j];
    }
    adtag[i] = 0;
}
void add(int l , int r , int x) {
    int p = bel[l] , q = bel[r];
    for (; p <= q; p++) {
        mx[p] += x , mi[p] += x , adtag[p] += x;
    }
    for (int i = l; i < L[p]; i++) {
        a[i] += x; sum[bel[i]] += x; mx[bel[i]] = max(mx[bel[i]] , a[i] + adtag[bel[i]]); mi[bel[i]] = min(mi[bel[i]] , a[i] + adtag[bel[i]]);
    }
    for (int i = R[q] + 1; i <= r; i++) {
        a[i] += x; sum[bel[i]] += x; mx[bel[i]] = max(mx[bel[i]] , a[i] + adtag[bel[i]]); mi[bel[i]] = min(mi[bel[i]] , a[i] + adtag[bel[i]]);
    }
}
void assign(int l , int r , int x) {
    int p = bel[l] , q = bel[r];
    for (; p <= q; p++) {
        mx[p] = x , mi[p] = x , adtag[p] = 0 , sum[p] = x * (R[p] - L[p] + 1);
    }
    for (int i = l; i < L[p]; i++) {
        sum[bel[i]] += x - a[i]; a[i] = x; mx[bel[i]] = max(mx[bel[i]] , a[i] + adtag[bel[i]]); mi[bel[i]] = min(mi[bel[i]] , a[i] + adtag[bel[i]]);
    }
    for (int i = R[q] + 1; i <= r; i++) {
        sum[bel[i]] += x - a[i]; a[i] = x; mx[bel[i]] = max(mx[bel[i]] , a[i] + adtag[bel[i]]); mi[bel[i]] = min(mi[bel[i]] , a[i] + adtag[bel[i]]);
    }
}
void Sqrt(int l , int r) {
    int p = bel[l] , q = bel[r];
    for (; p <= q; p++) {
        if (mx[p] > 1 || mi[p] < 0) {
            calc(p , L[p] , R[p]);
            for (int j = L[p]; j <= R[p]; j++) a[j] = (int)(sqrt(a[j]));
        }
    }
    calc(p - 1 , L[p - 1] , R[p - 1]);
    calc(q + 1 , L[q + 1] , R[q + 1]);
    for (int i = l; i < L[p]; i++) { if (a[i] >= 0) a[i] = sqrt(a[i]); }
    for (int i = R[q] + 1; i <= r; i++) { if (a[i] >= 0) a[i] = sqrt(a[i]); }
    calc(p - 1 , L[p - 1] , R[p - 1]);
    calc(q + 1 , L[q + 1] , R[q + 1]);
}
int Sum(int l , int r) {
    int res = 0;
    int p = bel[l] , q = bel[r];
    for (; p <= q; p++) {
        res += adtag[p] * (R[p] - L[p] + 1) + sum[p];
    }
    for (int i = l; i < L[p]; i++) { res += a[i] + adtag[bel[i]]; }
    for (int i = R[q] + 1; i <= r; i++) { res += a[i] + adtag[bel[i]]; }
    return res;
}
int Min(int l , int r) {
    int res = inf;
    int p = bel[l] , q = bel[r];
    for (; p <= q; p++) {
        res = min(res , mi[p] + adtag[p]);
    }
    for (int i = l; i < L[p]; i++) { res = min(res , a[i] + adtag[bel[i]]); }
    for (int i = R[q] + 1; i <= r; i++) { res = min(res , a[i] + adtag[bel[i]]); }
    return res;
}
int Max(int l , int r) {
    int res = -inf;
    int p = bel[l] , q = bel[r];
    for (; p <= q; p++) {
        res = max(res , mx[p] + adtag[p]);
    }
    for (int i = l; i < L[p]; i++) { res = max(res , a[i] + adtag[bel[i]]); }
    for (int i = R[q] + 1; i <= r; i++) { res = max(res , a[i] + adtag[bel[i]]); }
    return res;
}
void solve() { int n , q;
    cin >> n >> q; B = sqrt(n);
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= B; i++) {
        L[i] = (i - 1) * B + 1 , R[i] = i * B;
        calc(i , L[i] , R[i]);
    }
    if (n % B) ++B , L[B] = R[B - 1] + 1 , R[B] = n;
    calc(B , L[B] , R[B]);
    for (int i = 1 , op , l , r , x; i <= q; i++) {
        cin >> op >> l >> r;
        if (op == 1) cin >> x , add(l , r , x);
        else if (op == 2) cin >> x , assign(l , r , x);
        else if (op == 3) Sqrt(l , r);
        else if (op == 4) cout << Sum(l , r) << '\n';
        else if (op == 5) cout << Min(l , r) << '\n';
        else cout << Max(l , r) << '\n';
    }
}
signed main() {
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
    solve();
    return 0;
}
2024/7/31 18:09
加载中...