結果

問題 No.3507 RangeSum RangeUpdate RangeSqrt
コンテスト
ユーザー Kurao
提出日時 2026-04-22 09:52:18
言語 C++23
(gcc 15.2.0 + boost 1.89.0)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 339 ms / 2,000 ms
コード長 10,017 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 1,689 ms
コンパイル使用メモリ 226,240 KB
実行使用メモリ 24,320 KB
最終ジャッジ日時 2026-04-22 09:52:31
合計ジャッジ時間 10,341 ms
ジャッジサーバーID
(参考情報)
judge1_0 / judge2_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 29
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include<iostream>
#include<vector>
#include<array>
#include<queue>
#include<cmath>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <string>
#include <type_traits>
#include <utility>
#include <iterator>

using namespace std;
#define overload4(_1,_2,_3,_4,name,...) name

#define rep1(i,n) for (int i = 0; i < (n); ++i)
#define rep2(i,m,n) for (int i = (m); i < (n); ++i)
#define rep3(i,m,n,k) for (int i = (m); i < (n); i += (k))

#define rep(...) overload4(__VA_ARGS__, rep3, rep2, rep1)(__VA_ARGS__)

#define inf 1000000000

using namespace std;

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <string>
#include <type_traits>
#include <utility>
#include <iterator>

using namespace std;

// string はそのまま表示
ostream& operator<<(ostream& os, const string& s) {
    return os << '"' << s << '"';
}

// pair
template<class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    return os << "(" << p.first << ", " << p.second << ")";
}

// tuple
template<size_t N, class... Ts>
struct TuplePrinter {
    static void print(ostream& os, const tuple<Ts...>& t) {
        TuplePrinter<N - 1, Ts...>::print(os, t);
        os << ", " << get<N - 1>(t);
    }
};

template<class... Ts>
struct TuplePrinter<1, Ts...> {
    static void print(ostream& os, const tuple<Ts...>& t) {
        os << get<0>(t);
    }
};

template<class... Ts>
ostream& operator<<(ostream& os, const tuple<Ts...>& t) {
    os << "(";
    TuplePrinter<sizeof...(Ts), Ts...>::print(os, t);
    return os << ")";
}

// iterable 判定
template<typename T>
class is_iterable {
private:
    template<typename U>
    static auto test(int) -> decltype(
        std::begin(declval<U>()),
        std::end(declval<U>()),
        true_type{}
    );

    template<typename>
    static false_type test(...);

public:
    static constexpr bool value = decltype(test<T>(0))::value;
};

template<class T>
struct is_string : false_type {};

template<>
struct is_string<string> : true_type {};

// container 出力
template<class T>
typename enable_if<
    is_iterable<T>::value && !is_string<T>::value,
    ostream&
>::type
operator<<(ostream& os, const T& v) {
    os << "{";
    bool first = true;
    for (auto&& x : v) {
        if (!first) os << ", ";
        first = false;
        os << x;
    }
    return os << "}";
}

// C配列出力(char配列は除外)
template<class T, size_t N>
typename enable_if<!is_same<typename remove_cv<T>::type, char>::value, ostream&>::type
operator<<(ostream& os, const T (&a)[N]) {
    os << "{";
    for (size_t i = 0; i < N; i++) {
        if (i) os << ", ";
        os << a[i];
    }
    return os << "}";
}

#define debug(x) cerr << #x << " = " << (x) << endl

vector<pair<int,int>> dij = {{0,1}, {1,0}, {0,-1}, {-1,0}};

//using mint = modint998244353;

#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>

unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}

int countr_zero(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {
  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)bit_ceil((unsigned int)(_n));
        log = countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};
int isqrt(int n){
    double x=sqrt(n);
    int ans=(int)x;
    while ((ans+1)*(ans+1)<=n){
        ans++;
    }
    return ans;
};
struct S{
    long cnt_0;
    long cnt_1;
    array<long,5> fi;
};
S op(S x,S y){
    array<long,5> ans;
    rep (i,5){
        ans[i]=x.fi[i]+y.fi[i];
    }
    return S{x.cnt_0+y.cnt_0,x.cnt_1+y.cnt_1,ans};
};

S conv(long x){
    if (x==0){
        return S{1,0,{0,0,0,0,0}};
    } else {
        array<long,5> ans;
        ans[0]=x;
        rep(i,1,5){
            ans[i]=isqrt(ans[i-1]);
        }
        return S{1,1,ans};
    }
};

S rot(S x){
    array<long,5> ans;
    rep(i,4){
        ans[i]=x.fi[i+1];
    }
    ans[4]=x.cnt_1;
    return S{x.cnt_0,x.cnt_1,ans};
};

S mapping(long f,S x){
    if (f==-inf){
        return x;
    } else if (f<0) {
        S now=x;
        rep (i,-f){
            now=rot(now);
        }
        return now;
    } else {
        S ans=conv(f);
        array<long,5> final;
        rep(i,5){
            final[i]=ans.fi[i]*x.cnt_0;
        }
        return S{ans.cnt_0*x.cnt_0,ans.cnt_1*x.cnt_0,final};
    }
};

long composition(long f,long g){
    if (f==-inf){
        return g;
    } else if (g==-inf){
        return f;
    } else if (f>=0){
        return f;
    } else if (g>=0){
        return mapping(f,conv(g)).fi[0];
    } else {
        return f+g;
    }
};

S e(){
    return S{0,0,{0,0,0,0,0}};
}

long id(){
    return -inf;
};

int main(){
    long n,q;
    cin>>n>>q;
    vector<S> a(n);
    rep(_,n){
        long i;
        cin>>i;
        a[_]=conv(i);
    }
    lazy_segtree<S,op,e,long,mapping,composition,id> seg(a);
    rep(_,q){
        long t,l,r;
        cin>>t>>l>>r;
        if (t==0){
            cout<<seg.prod(l,r).fi[0]<<endl;
        } else if (t==1){
            long x;
            cin>>x;
            seg.apply(l,r,x);
        } else {
            seg.apply(l,r,-1);
        }
        //rep(i,n){
        //   cout<<seg.get(i).fi<<endl;
        //}
    }
}

0