Kevinx @ 2024-10-12 20:04:02
本人这题卡了两个月,最后被老师发现是函数返回值导致我RE和MLE,请问有人能解释一下是什么原因导致的吗?
程序第13行:
改之前:
ll pushup(ll p)
改成这个就ac了
void pushup(ll p)
所以一个定义了有返回值的函数但是不return会有什么影响?
by _Supernova @ 2024-10-12 20:06:17
请发完整代码。
by 大眼仔Happy @ 2024-10-12 20:07:26
ub 了解一下
by Estrella_Explore @ 2024-10-12 20:07:50
如果你启用较为严格的编译选项,你会获得类似于以下的警告:
./test.cpp: In function ‘long long int test()’:
./test.cpp:4:45: 警告:在有返回值的函数中未发现 return 语句 [-Wreturn-type]
4 | long long test() { cout << "Hello, world!"; }
|
#include <iostream>
using namespace std;
long long test() { cout << "Hello, world!"; }
int main() {
test();
return 0;
}
by Kevinx @ 2024-10-12 20:12:34
@_Supernova
RE+TLE
#include<bits/stdc++.h>
#define ll int
#define Mid ll mid = (l+r)>>1
using namespace std;
bool st;
const ll N = 5e5 + 20;
ll n, m, a[N], cnt = 0;
struct segtree{
ll maxv, maxl, maxr, sum;
}tree[N<<2];
ll ls(ll x) {return x<<1;}
ll rs(ll x) {return x<<1|1;}
ll pushup(ll p) {
tree[p].sum = tree[ls(p)].sum + tree[rs(p)].sum;
tree[p].maxl = max(tree[ls(p)].maxl, tree[ls(p)].sum+tree[rs(p)].maxl);
tree[p].maxr = max(tree[rs(p)].maxr, tree[rs(p)].sum+tree[ls(p)].maxr);
ll k1 = tree[ls(p)].maxr, k2 = tree[rs(p)].maxl;
ll K = max(max(k1, k2), k1+k2);
tree[p].maxv = max(max(tree[ls(p)].maxv, tree[rs(p)].maxv), K);
}
void build(ll p, ll l, ll r) {
if(l == r) {
tree[p].maxl = tree[p].maxr = tree[p].maxv = tree[p].sum = a[l];
return;
}
Mid;
build(ls(p), l, mid);
build(rs(p), mid+1, r);
pushup(p);
return ;
}
void change(ll p, ll l, ll r, ll x, ll k) {
Mid;
if(l == r) {
tree[p].maxl = tree[p].maxr = tree[p].maxv = tree[p].sum = k;
return ;
}
if(x <= mid) change(ls(p), l, mid, x, k);
if(x > mid) change(rs(p), mid+1, r, x, k);
pushup(p);
return ;
}
segtree query(ll p, ll l, ll r, ll x, ll y) {
if(x <= l && r <= y) {
return tree[p];
}
Mid;
segtree A = {0, 0, 0, 0}, B = {0, 0, 0, 0}, C1 = {0, 0, 0, 0};
bool vis1=0,vis2=0;
if(x <= mid) A = query(ls(p), l, mid, x, y), vis1 = 1;
if(y > mid) B = query(rs(p), mid+1, r, x, y), vis2 = 1;
if(vis1 == 1 && vis2 == 0) return A;
else if(vis1 == 0 && vis2 == 1) return B;
else {
C1.sum = A.sum + B.sum;
C1.maxl = max(A.maxl, A.sum+B.maxl);
C1.maxr = max(B.maxr, B.sum+A.maxr);
ll k1 = A.maxr, k2 = B.maxl;
ll K = max(max(k1, k2), k1+k2);
C1.maxv = max(max(A.maxv, B.maxv), K);
}
return C1;
}
bool ed;
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
build(1, 1, n);
segtree ans;
for(int i = 1; i <= m; i++) {
ll op, x, y;
cin >> op >> x >> y;
if(op == 2) {
// if(x>y) swap(x, y);
change(1, 1, n, x, y);
}
else{
if(x>y) swap(x, y);
ans = query(1, 1, n, x, y);
cout << ans.maxv << endl;
}
}
return 0;
}
/*
5 3
1
2
-3
4
5
1 4 5
*/
AC:
#include<bits/stdc++.h>
#define ll int
#define Mid ll mid = (l+r)>>1
using namespace std;
bool st;
const ll N = 5e5 + 20;
ll n, m, a[N], cnt = 0;
struct segtree{
ll maxv, maxl, maxr, sum;
}tree[N<<2];
ll ls(ll x) {return x<<1;}
ll rs(ll x) {return x<<1|1;}
void pushup(ll p) {
tree[p].sum = tree[ls(p)].sum + tree[rs(p)].sum;
tree[p].maxl = max(tree[ls(p)].maxl, tree[ls(p)].sum+tree[rs(p)].maxl);
tree[p].maxr = max(tree[rs(p)].maxr, tree[rs(p)].sum+tree[ls(p)].maxr);
ll k1 = tree[ls(p)].maxr, k2 = tree[rs(p)].maxl;
ll K = max(max(k1, k2), k1+k2);
tree[p].maxv = max(max(tree[ls(p)].maxv, tree[rs(p)].maxv), K);
}
void build(ll p, ll l, ll r) {
if(l == r) {
tree[p].maxl = tree[p].maxr = tree[p].maxv = tree[p].sum = a[l];
return;
}
Mid;
build(ls(p), l, mid);
build(rs(p), mid+1, r);
pushup(p);
return ;
}
void change(ll p, ll l, ll r, ll x, ll k) {
Mid;
if(l == r) {
tree[p].maxl = tree[p].maxr = tree[p].maxv = tree[p].sum = k;
return ;
}
if(x <= mid) change(ls(p), l, mid, x, k);
if(x > mid) change(rs(p), mid+1, r, x, k);
pushup(p);
return ;
}
segtree query(ll p, ll l, ll r, ll x, ll y) {
if(x <= l && r <= y) {
return tree[p];
}
Mid;
segtree A = {0, 0, 0, 0}, B = {0, 0, 0, 0}, C1 = {0, 0, 0, 0};
bool vis1=0,vis2=0;
if(x <= mid) A = query(ls(p), l, mid, x, y), vis1 = 1;
if(y > mid) B = query(rs(p), mid+1, r, x, y), vis2 = 1;
if(vis1 == 1 && vis2 == 0) return A;
else if(vis1 == 0 && vis2 == 1) return B;
else {
C1.sum = A.sum + B.sum;
C1.maxl = max(A.maxl, A.sum+B.maxl);
C1.maxr = max(B.maxr, B.sum+A.maxr);
ll k1 = A.maxr, k2 = B.maxl;
ll K = max(max(k1, k2), k1+k2);
C1.maxv = max(max(A.maxv, B.maxv), K);
}
return C1;
}
bool ed;
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
build(1, 1, n);
segtree ans;
for(int i = 1; i <= m; i++) {
ll op, x, y;
cin >> op >> x >> y;
if(op == 2) {
change(1, 1, n, x, y);
}
else{
if(x>y) swap(x, y);
ans = query(1, 1, n, x, y);
cout << ans.maxv << endl;
}
}
return 0;
}
/*
5 3
1
2
-3
4
5
1 4 5
*/
by exploration @ 2024-10-12 20:13:35
@Kevinx 定义了有返回值的函数但不写return语句会导致函数默认返回None,那么就会RE
by Kevinx @ 2024-10-12 20:26:06
@_Supernova @大眼仔Happy @Estrella_Explore @exploration 感谢
by Terrible @ 2024-10-12 20:30:10
具体原因:非 void 函数执行时没有返回值,则洛谷 GCC 编译出的汇编对应位置没有 ret 从而执行时代码串行,从而可能出各种错误,当然也可能莫名其妙没有问题。
开 O2 时串行出错的概率更大,不开 O2 时有可能会编译出来一个 ret 从而防范了出错,但是不能保证一定有 ret。
规范上,应当给所有 非 void 函数的所有可访问的情况都设定 return。核心要求是程序完整执行的时候函数必须 return,而并非要求这个函数对任意输入都必须有明确返回值。
by Kevinx @ 2024-10-12 20:36:55
@Terrible 拜谢dalao