求助!!我用两种方法写(差分和维护等差数列)样例都爆8,有没有大佬帮忙看看啊!!! 差分:
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
const int maxn = 1e5 + 1;
int sum[4 * maxn];
int tag[4 * maxn];
int n, m;
inline void make_tag(int idx, int len, int val) {
sum[idx] += val * len;
tag[idx] += val;
}
inline void push_down(int idx, int l, int r) {
int mid = l + (r - l) / 2;
make_tag(idx * 2, mid - l + 1, tag[idx]);
make_tag(idx * 2 + 1, r - mid, tag[idx]);
tag[idx] = 0;
}
void pull_up(int idx) {
sum[idx] = sum[idx * 2] + sum[idx * 2 + 1];
}
void update(int idx, int l, int r, int tar_l, int tar_r, int val) {
if(tar_l <= l && r <= tar_r) {
make_tag(idx, r - l + 1, val);
return;
} else if(r < tar_l || l > tar_r)
return;
int mid = l + (r - l) / 2;
push_down(idx, l, r);
update(idx * 2, l, mid, tar_l, tar_r, val);
update(idx * 2 + 1, mid + 1, r, tar_l, tar_r, val);
pull_up(idx);
}
inline void update(int l, int r, int val) {
update(1, 1, n, l, r, val);
}
int ask(int idx, int l, int r, int tar_l, int tar_r) {
if(tar_l <= l && r <= tar_r)
return sum[idx];
else if(r < tar_l || l > tar_r)
return 0;
int mid = l + (r - l) / 2;
push_down(idx, l, r);
return ask(idx * 2, l, mid, tar_l, tar_r) + ask(idx * 2 + 1, mid + 1, r, tar_l, tar_r);
}
inline int ask(int pos) {
return ask(1, 1, n, 1, pos);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m;
int *origin = new int[maxn + 1];
for(int i = 1; i <= n; i++)
cin >> origin[i];
origin[0] = 0;
function<void(int, int, int)> helper = [&](int idx, int l, int r) {
if(l == r) {
sum[idx] = origin[l] - origin[l - 1];
return;
}
int mid = l + (r - l) / 2;
helper(idx * 2, l, mid);
helper(idx * 2 + 1, mid + 1, r);
pull_up(idx);
};
helper(1, 1, n);
delete[] origin;
for(int i = 1; i <= m; i++) {
char opt; cin >> opt;
if(opt == '1') {
int l, r, k, d;
cin >> l >> r >> k >> d;
update(l, r, d);
update(l, l, k);
update(r + 1, r + 1, -k);
} else {
int pos; cin >> pos;
cout << ask(pos) << endl;
}
}
return 0;
}
维护等差数列:
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
const int maxn = 1e5;
int sum[4 * maxn], tag_k[4 * maxn], tag_d[4 * maxn];
int n, m;
inline int S(int k, int d, int len) {
return k * len + d * (len - 1) * len / 2;
}
inline void make_tag(int idx, int len, int k, int d) {
sum[idx] += S(k, d, len);
tag_d[idx] += d;
tag_k[idx] += k;
}
inline void push_down(int idx, int l, int r) {
int mid = l + (r - l) / 2;
make_tag(idx * 2, mid - l + 1, tag_k[idx], tag_d[idx]);
make_tag(idx * 2 + 1, r - mid, tag_k[idx] + (mid - l + 1) * tag_d[idx], tag_d[idx]);
tag_k[idx] = 0;
tag_d[idx] = 0;
}
void pull_up(int idx) {
sum[idx] = sum[idx * 2] + sum[idx * 2 + 1];
}
void update(int idx, int l, int r, int tar_l, int tar_r, int k, int d) {
if(tar_l <= l && r <= tar_r) {
make_tag(idx, r - l + 1, k, d);
return;
} else if(r < tar_l || l > tar_r)
return;
int mid = l + (r - l) / 2;
push_down(idx, l, r);
update(idx * 2, l, mid, tar_l, tar_r, k, d);
update(idx * 2 + 1, mid + 1, r, tar_l, tar_r, k + (mid - l + 1) * d, d);
pull_up(idx);
}
inline void update(int l, int r, int k, int d) {
update(1, 1, n, l, r, k, d);
}
int ask(int idx, int l, int r, int tar_l, int tar_r) {
if(tar_l <= l && r <= tar_r)
return sum[idx];
else if(r < tar_l || l > tar_r)
return 0;
int mid = l + (r - l) / 2;
push_down(idx, l, r);
return ask(idx * 2, l, mid, tar_l, tar_r) + ask(idx * 2 + 1, mid + 1, r, tar_l, tar_r);
}
inline int ask(int l, int r) {
return ask(1, 1, n, l, r);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m;
int *origin = new int[maxn + 1];
for(int i = 1; i <= n; i++)
cin >> origin[i];
function<void(int, int, int)> helper = [&](int idx, int l, int r) {
if(l == r) {
sum[idx] = origin[l];
return;
}
int mid = l + (r - l) / 2;
helper(idx * 2, l, mid);
helper(idx * 2 + 1, mid + 1, r);
pull_up(idx);
};
helper(1, 1, n);
delete[] origin;
for(int i = 1; i <= m; i++) {
char opt; cin >> opt;
if(opt == '1') {
int l, r, k, d;
cin >> l >> r >> k >> d;
update(l, r, k, d);
} else {
int pos; cin >> pos;
cout << ask(pos, pos) << endl;
}
}
return 0;
}
球球帮忙