Nuclear_Fish_cyq @ 2023-07-07 20:57:20
【赏关】线段树板子样例已过WA0pts带hack数据码风不离谱求调
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n, m, opt, x, y, k, a[100005];
struct segment{
ll l, r, sum, lazy;
}b[500000];
void build(ll s, ll e, ll t){
b[t].l = s;
b[t].r = e;
if(s == e){
b[t].sum = a[s];
return;
}
ll p = s + ((e - s) >> 1);
build(s, p, t * 2);
build(p + 1, e, t * 2 + 1);
b[t].sum = b[t * 2].sum + b[t * 2 - 1].sum;
return;
}
ll scarch(ll t){
if(x <= b[t].l && y >= b[t].r){
return b[t].sum;
}
ll p = b[t].l + ((b[t].r - b[t].l) >> 1);
if(b[t].lazy){
b[t * 2].sum += b[t].lazy * (p - b[t].l + 1);
b[t * 2 + 1].sum += b[t].lazy * (b[t].r - p);
b[t * 2].lazy += b[t].lazy;
b[t * 2 + 1].lazy += b[t].lazy;
}
b[t].lazy = 0;
ll ans = 0;
if(x <= p){
ans += scarch(t * 2);
}
if(y > p){
ans += scarch(t * 2 + 1);
}
return ans;
}
void update(ll t){
if(x <= b[t].l && y >= b[t].r){
b[t].sum += (b[t].r - b[t].l + 1) * k;
b[t].lazy += k;
return;
}
ll p = b[t].l + ((b[t].r - b[t].l) >> 1);
if(b[t].lazy){
b[t * 2].sum += b[t].lazy * (p - b[t].l + 1);
b[t * 2 + 1].sum += b[t].lazy * (b[t].r - p);
b[t * 2].lazy += b[t].lazy;
b[t * 2 + 1].lazy += b[t].lazy;
}
b[t].lazy = 0;
if(x <= p){
update(t * 2);
}
if(y > p){
update(t * 2 + 1);
}
b[t].sum = b[t * 2].sum + b[t * 2 + 1].sum;
return;
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
cin >> a[i];
}
build(1, n, 1);
for(int i = 0; i < m; i++){
cin >> opt;
if(opt == 1){
cin >> x >> y >> k;
update(1);
}
else{
cin >> x >> y;
cout << scarch(1) << endl;
}
}
return 0;
}
hack数据:
输入:
8 10
640 591 141 307 942 58 775 133
2 1 5
2 3 8
2 3 6
2 5 8
2 4 8
1 4 8 60
2 1 6
2 5 8
1 3 7 15
1 2 6 86
正确输出:
2621
2356
1448
1908
2215
2859
2148
我的输出:
1582
2713
1981
1981
2288
2517
2221
我认为因为hack数据一上来就是输出操作,所以main(),build()和scarch()里面一定有至少一个错误,但与oi.wiki的代码比对多次无果。
by hjqhs @ 2023-07-07 21:06:44
你的 build 有一个地方打成 -1 了
by hjqhs @ 2023-07-07 21:07:36
@Cyq_Lyw_01 build最后pushup那里
by Nuclear_Fish_cyq @ 2023-07-07 21:07:55
@hjqhs thx!!!!!!!!!!已过,已关注,此贴结
by Nuclear_Fish_cyq @ 2023-07-07 21:08:15
wssb!!!!!
by Phrvth @ 2023-07-07 21:10:21
@Cyq_Lyw_01 第18行的
b[t].sum = b[t 2].sum + b[t 2 - 1].sum;
应为
b[t].sum = b[t 2].sum + b[t 2 + 1].sum;
建议: 建议写函数,比如
ls(i) = i<<1
rs(i)= i<<1|1
push_up()
push_down()
我这里把我的代码放这里,仅供参考
(个人比较喜欢用结构体封装数据结构)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 1e5 + 7;
int n, m, a[MAXN];
struct Segt_Tree{
struct Node{int sum, lg; }t[MAXN * 4];
#define ls(i) (i << 1)
#define rs(i) (i << 1 | 1)
inline void push_up(int x) {t[x].sum = t[ls(x)].sum + t[rs(x)].sum; }
inline void build(int cur, int l, int r){
if (l == r) {
t[cur].sum = a[l];
return ;
}
int mid = l + r >> 1;
build(ls(cur), l, mid); build(rs(cur), mid + 1, r);
push_up(cur);
}
inline void f(int cur, int l, int r, int k){
t[cur].sum += (r - l + 1) * k;
t[cur].lg += k;
}
inline void push_down(int cur, int l, int r) {
int mid = l + r >> 1;
f(ls(cur), l, mid, t[cur].lg);
f(rs(cur), mid + 1, r, t[cur].lg);
t[cur].lg = 0;
}
inline void modify(int cur, int l, int r, int x, int y, int k) {
if (x <= l && y >= r) {
f(cur, l, r, k);
return ;
}
int mid = l + r >> 1;
push_down(cur, l, r);
if (x <= mid) modify(ls(cur), l, mid, x, y, k);
if (y > mid ) modify(rs(cur), mid + 1, r, x, y ,k);
push_up(cur);
}
inline int query(int cur, int l, int r, int x, int y) {
if (x <= l && y >= r) return t[cur].sum;
int mid = l + r >> 1, ans = 0;
push_down(cur, l, r);
if (x <= mid) ans += query(ls(cur), l, mid, x, y);
if (y > mid ) ans += query(rs(cur), mid + 1, r, x, y);
return ans;
}
}t;
signed main () {
cin >> n >> m;
for (int i = 1; i <= n; i ++) cin >> a[i];
t.build(1, 1, n);
for (int i = 1, flag; i <= m; i ++) {
cin >> flag;
if (flag == 1) {
int x, y, k;
cin >> x >> y >> k;
t.modify(1, 1, n, x, y, k);
} else if (flag == 2) {
int x, y;
cin >> x >> y;
cout << t.query(1, 1, n, x, y) << '\n';
}
}
return 0;
}
by Nuclear_Fish_cyq @ 2023-07-07 21:10:57
@Phrvth 谢谢,也关注了