結果
| 問題 |
No.1000 Point Add and Array Add
|
| コンテスト | |
| ユーザー |
Dente
|
| 提出日時 | 2020-02-28 21:55:16 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 571 ms / 2,000 ms |
| コード長 | 3,916 bytes |
| コンパイル時間 | 1,940 ms |
| コンパイル使用メモリ | 182,316 KB |
| 実行使用メモリ | 17,040 KB |
| 最終ジャッジ日時 | 2024-10-13 17:20:40 |
| 合計ジャッジ時間 | 7,427 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 22 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < (n); i++)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
using P = pair<int, int>;
const int INF = 1e9;
const long long LINF = 1e18;
const long long MOD = 1e9 + 7;
/*
LazySegmentTree<ll, ll> seg(f, g, h, p, def, laz_def) のように宣言する
RMQ and RUQ の場合 :
auto f = [](ll a, ll b){return min(a, b);};
auto g = [](ll a, ll b){return b;};
auto h = [](ll a, ll b){return b;};
auto p = [](ll a, ll b){return a;};
RSQ and RAQ の場合 :
auto f = [](ll a, ll b){return a + b;};
auto g = [](ll a, ll b){return a + b;};
auto h = [](ll a, ll b){return a + b;};
auto p = [](ll a, int b){return a * b;};
*/
template <typename Monoid, typename OperatorMonoid>
struct LazySegmentTree{
using F = function<Monoid(Monoid, Monoid)>;
using G = function<Monoid(Monoid, OperatorMonoid)>;
using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
using P = function<OperatorMonoid(OperatorMonoid, int)>;
int n;
vector<Monoid> dat;
vector<OperatorMonoid> laz;
F f;
G g;
H h;
P p;
Monoid def;
OperatorMonoid laz_def;
LazySegmentTree(F f, G g, H h, P p, Monoid def, OperatorMonoid laz_def) : f(f), g(g), h(h), p(p), def(def), laz_def(laz_def){}
void build(const vector<Monoid> & vec){
int siz = vec.size();
n = 1;
while(n < siz) n *= 2;
dat.assign(2 * n - 1, def);
laz.assign(2 * n - 1, laz_def);
for(int i = 0; i < siz; i++) dat[n - 1 + i] = vec[i];
for(int i = n - 2; i >= 0; i--) dat[i] = f(dat[2 * i + 1], dat[2 * i + 2]);
}
void update(int a, int b, OperatorMonoid x){
update(a, b, x, 0, 0, n);
}
Monoid query(int a, int b){
return query(a, b, 0, 0, n);
}
private:
void eval(int k, int l, int r){
if(laz[k] != laz_def){
dat[k] = g(dat[k], p(laz[k], r - l));
if(r - l > 1){
laz[2 * k + 1] = h(laz[2 * k + 1], laz[k]);
laz[2 * k + 2] = h(laz[2 * k + 2], laz[k]);
}
laz[k] = laz_def;
}
}
void update(int a, int b, OperatorMonoid x, int k, int l, int r){
eval(k, l, r);
if(r <= a || b <= l) return;
if(a <= l && r <= b){
laz[k] = h(laz[k], x);
eval(k, l, r);
}else{
update(a, b, x, 2 * k + 1, l, (l + r) / 2);
update(a, b, x, 2 * k + 2, (l + r) / 2, r);
dat[k] = f(dat[2 * k + 1], dat[2 * k + 2]);
}
}
Monoid query(int a, int b, int k, int l, int r){
if(r <= a || b <= l) return def;
eval(k, l, r);
if(a <= l && r <= b) return dat[k];
Monoid vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
Monoid vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
return f(vl, vr);
}
};
signed main(){
int n,q;
cin >> n >> q;
vector<ll> a(n);
rep(i,n){
cin >> a[i];
}
vector<pair<char, pair<int, int>>> v(q);
rep(i,q){
cin >> v[i].first >> v[i].second.first >> v[i].second.second;
}
reverse(ALL(v));
auto f = [](ll a, ll b){return a + b;};
auto g = [](ll a, ll b){return a + b;};
auto h = [](ll a, ll b){return a + b;};
auto p = [](ll a, int b){return a * b;};
LazySegmentTree<ll, ll> seg(f, g, h, p, 0, 0);
seg.build(vector<ll>(n, 0));
vector<ll> ans(n, 0);
rep(i,q){
if(v[i].first == 'A'){
ans[v[i].second.first - 1] += seg.query(v[i].second.first - 1, v[i].second.first) * v[i].second.second;
}else{
seg.update(v[i].second.first - 1, v[i].second.second, 1);
}
}
rep(i,n){
ans[i] += seg.query(i, i + 1) * a[i];
}
rep(i,n){
if(i) cout << " ";
cout << ans[i];
}
cout << endl;
return 0;
}
Dente