結果
| 問題 | No.3494 一点挿入区間和取得 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-04-03 22:37:08 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 175 ms / 6,000 ms |
| コード長 | 10,158 bytes |
| 記録 | |
| コンパイル時間 | 4,814 ms |
| コンパイル使用メモリ | 380,148 KB |
| 実行使用メモリ | 8,704 KB |
| 最終ジャッジ日時 | 2026-04-03 22:37:20 |
| 合計ジャッジ時間 | 9,335 ms |
|
ジャッジサーバーID (参考情報) |
judge3_1 / judge5_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 23 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision;
#define ll long long
#define ld long double
#define rep(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define vi vector<int>
#define vl vector<ll>
#define vd vector<double>
#define vb vector<bool>
#define vs vector<string>
#define vc vector<char>
#define ull unsigned long long
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
template<class T, class U>
inline bool chmax(T &a, const U &b) {
if (a < b) {
a = b;
return true;
}
return false;
}
template<class T, class U>
inline bool chmin(T &a, const U &b) {
if (a > b) {
a = b;
return true;
}
return false;
}
// #define ll int
// #define ll int128_t
// #define ll int256_t
// #define ll cpp_int
constexpr ll inf = (1ll << 60);
// constexpr ll inf = (1 << 30);
// const double PI=3.1415926535897932384626433832795028841971;
// ll rui(ll a,ll b){
// if(b==0)return 1;
// if(b%2==1) return a*rui(a*a,b/2);
// return rui(a*a,b/2);
// }
// vl fact;
// ll kai(ll n){
// fact.resize(n,1);
// rep(i,n-1)fact[i+1]=fact[i]*(i+1);
// }
// using mint = ld;
using mint = modint998244353;//static_modint<998244353>
// using mint = modint1000000007;//static_modint<1000000007>
// using mint = static_modint<922267487>; // 多分落とされにくい NOT ntt-friendly
// using mint = static_modint<469762049>; // ntt-friendly
// using mint = static_modint<167772161>; // ntt-friendly
// using mint = modint;//mint::set_mod(mod);
// ll const mod=1000000007ll;
// ll const mod=998244353ll;
// ll modrui(ll a,ll b,ll mod){
// a%=mod;
// if(b==0)return 1;
// if(b%2==1) return a*modrui(a*a%mod,b/2,mod)%mod;
// return modrui(a*a%mod,b/2,mod)%mod;
// }
// ll inv(ll x){
// x%=mod;
// return modrui(x,mod-2);
// }
// void incr(vl &v,ll n){// n進法
// ll k=v.size();
// v[k-1]++;
// ll now=k-1;
// while (v[now]>=n)
// {
// v[now]=0;
// if(now==0)break;
// v[now-1]++;
// now--;
// }
// return;
// }
// vector<mint> fact,invf;
// void init_modfact(ll sz){
// fact.resize(sz);
// invf.resize(sz);
// fact[0]=1;
// rep(i,sz-1){
// fact[i+1]=fact[i]*(i+1);
// }
// invf[sz-1]=1/fact[sz-1];
// for(ll i=sz-2; i>=0; i--){
// invf[i]=invf[i+1]*(i+1);
// }
// }
// mint choose(ll n,ll r){
// if(n<r || r<0)return 0;
// return fact[n]*invf[r]*invf[n-r];
// }
vector<mint> modpow,invpow;
void init_modpow(ll x,ll sz){
mint inv=1/mint(x);
modpow.assign(sz,1);
invpow.assign(sz,1);
rep(i,sz-1){
modpow[i+1]=modpow[i]*x;
invpow[i+1]=invpow[i]*inv;
}
}
// long long phi(long long n) {// O(sqrt(n))
// long long res = n;
// for (long long i = 2; i * i <= n; i++) {
// if (n % i == 0) {
// res -= res / i;
// while (n % i == 0) n /= i;
// }
// }
// if (n > 1) res -= res / n;
// return res;
// }
ll ceil(ll a,ll b){
ll k=a/b;
if(b*(k-1)>=a)return k-1;
if(b*k>=a)return k;
if(b*(k+1)>=a)return k+1;
return 0;
}
ll floor(ll a,ll b){
ll k=a/b;
if(b*(k+1)<=a)return k+1;
if(b*k<=a)return k;
if(b*(k-1)<=a)return k-1;
return 0;
}
// https://judge.yosupo.jp/submission/326817
template<
typename S, typename F,
S (*op)(S, S),
S (*e)(),
S (*mapping)(F, S),
F (*composition)(F, F),
F (*id)(),
S (*rev_op)(S)
>
struct implicit_treap {
struct Node {
S val; // single element value
S sum; // aggregated value of subtree (順序依存)
int sz;
unsigned pri;
Node *l, *r;
F lazy;
bool has_lazy;
bool rev; // reverse flag
Node(const S &v, unsigned p): val(v), sum(v), sz(1), pri(p), l(nullptr), r(nullptr), lazy(id()), has_lazy(false), rev(false) {}
void pull(){
// subtree の集合を左->val->右 の順で計算
sum = val;
sz = 1;
if(l){ sum = op(l->sum, sum); sz += l->sz; }
if(r){ sum = op(sum, r->sum); sz += r->sz; }
}
void apply_lazy(const F &f){
// 写像 f を val と sum に適用
val = mapping(f, val);
sum = mapping(f, sum);
if(has_lazy){
// 新しい f を既存 lazy の前に適用する(apply f after existing lazy)
lazy = composition(f, lazy);
}else{
lazy = f;
has_lazy = true;
}
}
void apply_rev(){
// 節点を反転:子をswapし、val/sum を rev_op で反転表現に変える
rev = !rev;
std::swap(l, r);
val = rev_op(val);
sum = rev_op(sum);
}
void push(){
// 子へ遅延写像を伝搬
if(has_lazy){
if(l) l->apply_lazy(lazy);
if(r) r->apply_lazy(lazy);
lazy = id();
has_lazy = false;
}
// 子へ反転フラグを伝搬(apply_rev は子の構造も入れ替える)
if(rev){
if(l) l->apply_rev();
if(r) r->apply_rev();
rev = false;
}
}
};
Node *root;
std::mt19937_64 rng;
implicit_treap(): root(nullptr), rng((unsigned)chrono::high_resolution_clock::now().time_since_epoch().count()) {}
~implicit_treap(){
destroy(root);
}
void destroy(Node *t){
if(!t) return;
destroy(t->l);
destroy(t->r);
delete t;
}
int size() const { return root ? root->sz : 0; }
Node* make_node(const S &v){
return new Node(v, (unsigned)(rng() >> 1));
}
// split by first k elements: [0,k) and [k, n)
pair<Node*, Node*> split(Node *t, int k){
if(!t) return {nullptr, nullptr};
t->push();
int lsz = t->l ? t->l->sz : 0;
if(k <= lsz){
auto pr = split(t->l, k);
t->l = pr.second;
t->pull();
return {pr.first, t};
}else{
auto pr = split(t->r, k - lsz - 1);
t->r = pr.first;
t->pull();
return {t, pr.second};
}
}
Node* merge(Node *a, Node *b){
if(!a) return b;
if(!b) return a;
if(a->pri > b->pri){
a->push();
a->r = merge(a->r, b);
a->pull();
return a;
}else{
b->push();
b->l = merge(a, b->l);
b->pull();
return b;
}
}
// build from vector of S
Node* build_from_vector(const vector<S> &v){
Node *t = nullptr;
for(const S &x : v){
t = merge(t, make_node(x));
}
return t;
}
void build(const vector<S> &v){
destroy(root);
root = build_from_vector(v);
}
// get element at index i (0-index)
S get(int i){
Node *t = root;
while(t){
t->push();
int lsz = t->l ? t->l->sz : 0;
if(i < lsz) t = t->l;
else if(i == lsz) return t->val;
else { i -= lsz + 1; t = t->r; }
}
return e(); // out of range -> return identity
}
// insert element at position pos (0-index, insert before pos)
void insert(int pos, const S &v){
assert(0<=pos && pos<=(this->size()));
auto pr = split(root, pos);
Node *n = make_node(v);
root = merge(merge(pr.first, n), pr.second);
}
// erase element at position pos
void erase(int pos){
assert(0<=pos && pos<=(this->size()));
auto a = split(root, pos);
auto b = split(a.second, 1); // b.first is node to erase
destroy(b.first);
root = merge(a.first, b.second);
}
// apply mapping f to range [l, r) (0-index half-open)
void apply(int l, int r, const F &f){
assert(0<=l && r<=(this->size()) && l<=r);
if(l >= r) return;
auto a = split(root, l);
auto b = split(a.second, r - l);
if(b.first) b.first->apply_lazy(f);
root = merge(a.first, merge(b.first, b.second));
}
// reverse range [l,r) (0-index half-open)
void range_reverse(int l, int r){
assert(0<=l && r<=(this->size()) && l<=r);
if(l >= r) return;
auto a = split(root, l);
auto b = split(a.second, r - l);
if(b.first) b.first->apply_rev();
root = merge(a.first, merge(b.first, b.second));
}
// query aggregate on [l, r)
S prod(int l, int r){
assert(0<=l && r<=(this->size()) && l<=r);
if(l >= r) return e();
auto a = split(root, l);
auto b = split(a.second, r - l);
S res = b.first ? b.first->sum : e();
root = merge(a.first, merge(b.first, b.second));
return res;
}
// inorder -> vector
void to_vector(Node *t, vector<S> &out){
if(!t) return;
t->push();
to_vector(t->l, out);
out.push_back(t->val);
to_vector(t->r, out);
}
vector<S> to_vector(){
vector<S> v;
v.reserve(size());
to_vector(root, v);
return v;
}
};
// struct S{};
#define S ll
// struct F{};
#define F ll
S op(S l,S r){return l+r;}
S e(){return 0;}
S mapping(F f,S s){return s;}
F id(){return 0;}
F composition(F f,F g){return 0;}
S rev_op(S s){return s;}
void solve(){
ll n,q;
cin >> n >> q;
implicit_treap<S,F,op,e,mapping,composition,id,rev_op> treap;
rep(i,n){
ll a;
cin >> a;
treap.insert(i,a);
}
while(q--){
ll i,x,l,r;
cin >> i >> x >> l >> r;
l--;
treap.insert(i,x);
cout << treap.prod(l,r) << endl;
}
}
int main(){
// ios::sync_with_stdio(false);
// std::cin.tie(nullptr);
ll t = 1;
// cin >> t;
while (t--) solve();
}