今天写RMQ算法的模板,竟然出现了时而AC时而WA的情况,十分的不理解。同样的程序,改变全局变量的定义次序,结果就不同,但是在本地测试却是正确的,POJ的服务器Judge编译环境应该是和我的本地配置不同,幸好发现了这样的问题,不然正式比赛的时候肯定会败得很惨,错误都不知道去哪里寻找。
#i nclude <iostream>
#i nclude <cmath>
#i nclude <algorithm>
using namespace std;
const int range=50000;
#define DEF 40
int minr[DEF][range],maxr[DEF][range];
int arr[range];
void initial(int *arr,int n){
int i,j,fac;
memset(minr,0,sizeof(minr));
memset(maxr,0,sizeof(maxr));
for (i=1; i<=n; ++i){
minr[0][i]=arr[i];
maxr[0][i]=arr[i];
}
fac=1;j=0;
while (fac*2<n){
fac*=2;
j++;
int te=n-fac+1;
for (i=1; i<=te; ++i){
minr[j][i]=min(minr[j-1][i],minr[j-1][i+fac/2]);
maxr[j][i]=max(maxr[j-1][i],maxr[j-1][i+fac/2]);
}
}
}
int query_min(int low,int up){
int k;
k=(int)(log(up-low+1)/log(2));
return min(minr[k][low],minr[k][up-(int)pow(2,(double)k)+1]);
}
int query_max(int low,int up){
int k;
k=(int)(log(up-low+1)/log(2));
return max(maxr[k][low],maxr[k][up-(int)pow(2,(double)k)+1]);
}
int main(){
int i;
int n,query;
int low,up;
scanf("%d%d",&n,&query);
for (i=1; i<=n; ++i){
scanf("%d",&arr[i]);
}
initial(arr,n);
for (i=1; i<=query; ++i){
scanf("%d%d",&low,&up);
printf("%d\n",query_max(low,up)-query_min(low,up));
}
return 0;
}
问题在于,当我把n,query,low,up也定义成全局变量,而且次序放在arr序列的前面时,程序可以正常的ACPKU3264,但是一旦改变定义次序,比如定义成如下的次序,就出现问题:
int arr[range];
int n,query;
int low,up;
这样进行定义是不能通过本道题目的。思考了很久,问题应该存在于变量的作用域上。
拿relic写的模板也进行了测试,结果和我猜测的是一样的。
平时都没怎么注意这个问题。