Submission #68361


ソースコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define vi vector<int>
#define all(v) v.begin(),v.end()
#define fi first
#define se second
#define P pair<int,int>
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
vector<ll> b(200005,0);
int ori=1000000;
struct LazySegmentTree {
int n;
vector<ll> node, lazy;
LazySegmentTree(vector<ll> v) {
int sz = (int)v.size();
n = 1; while(n < sz) n *= 2;
node.resize(2*n-1);
lazy.resize(2*n-1,ori);
for(int i=0; i<sz; i++) node[i+n-1] = v[i];
for(int i=n-2; i>=0; i--) node[i] = node[i*2+1] + node[i*2+2];
}
//k番目のノードについて遅延評価
void eval(int k, int l, int r) {
//遅延配列が空でない場合、自ノード及び子ノードへの値の伝播
if(lazy[k] != ori) {
node[k] = b[r-1+lazy[k]]-b[l-1+lazy[k]];
//最下段かどうかチェック&子ノードは親ノードの1/2なので半分にして伝播
if(r - l > 1) {
lazy[2*k+1] = lazy[k];
lazy[2*k+2] = lazy[k];
}
//伝播が終わったので、自ノードの遅延配列を空にする
lazy[k] = ori;
}
}
void add(int a, int b, int x, int k=0, int l=0, int r=-1) {
if(r < 0) r = n;
//遅延評価
eval(k, l, r);
if(b <= l || r <= a) return;
//完全に被覆しているならば、遅延配列に値を入れた後に評価
if(a <= l && r <= b) {
lazy[k] = x;
eval(k, l, r);
}
else {
add(a, b, x, 2*k+1, l, (l+r)/2);
add(a, b, x, 2*k+2, (l+r)/2, r);
node[k] = node[2*k+1] + node[2*k+2];
}
}
ll getsum(int a, int b, int k=0, int l=0, int r=-1) {
if(r < 0) r = n;
if(b <= l || r <= a) return 0;
//遅延評価したあとに取得
eval(k, l, r);
if(a <= l && r <= b) return node[k];
ll vl = getsum(a, b, 2*k+1, l, (l+r)/2);
ll vr = getsum(a, b, 2*k+2, (l+r)/2, r);
return vl + vr;
}
};
int main(){
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
int n,m; cin>>n>>m;
vector<ll> a(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
}
LazySegmentTree st(a);
for(int i=1;i<=n;i++){
cin>>b[i];
}
for(int i=1;i<=n;i++){
b[i]+=b[i-1];
}
for(int i=0;i<m;i++){
int op; cin>>op;
if(op==0){
int x,y,z; cin>>x>>y>>z;
st.add(x,x+z,y-x);
}
else{
int p,q; cin>>p>>q;
cout<<st.getsum(p,q+1)<<"\n";
}
}
return 0;
}

ステータス

項目 データ
問題 1446 - Copy&Sum
ユーザー名 ei2005
投稿日時 2021-09-08 16:27:52
言語 C++17
状態 Accepted
得点 12
ソースコード長 2916 Byte
最大実行時間 222 ms
最大メモリ使用量 20124 KB

セット

セット 得点 Cases
1 ALL 12 / 12 *

テストケース

ファイル名 状態 実行時間 メモリ使用量 #
in1 AC 28 ms 2140 KB
1
in2 AC 28 ms 2100 KB
1
in3 AC 22 ms 10124 KB
1
in4 AC 22 ms 10180 KB
1
in5 AC 17 ms 10104 KB
1
in6 AC 21 ms 10156 KB
1
in7 AC 18 ms 10212 KB
1
in8 AC 20 ms 10268 KB
1
in9 AC 21 ms 10192 KB
1
in10 AC 28 ms 1936 KB
1
in11 AC 29 ms 1996 KB
1
in12 AC 18 ms 2056 KB
1
in13 AC 21 ms 2116 KB
1
in14 AC 17 ms 2044 KB
1
in15 AC 17 ms 2092 KB
1
in16 AC 23 ms 2136 KB
1
in17 AC 31 ms 2176 KB
1
in18 AC 27 ms 2072 KB
1
in19 AC 24 ms 2076 KB
1
in20 AC 20 ms 2156 KB
1
in21 AC 181 ms 13420 KB
1
in22 AC 175 ms 14424 KB
1
in23 AC 194 ms 15944 KB
1
in24 AC 222 ms 17332 KB
1
in25 AC 145 ms 18856 KB
1
in26 AC 153 ms 20124 KB
1