访问数组-1位置返回-1?
查看原帖
访问数组-1位置返回-1?
936078
SinCircle楼主2023/10/5 11:39

我最开始没注意到是返回编号,改成返回编号之后直接交了一发,竟然过了

回头给同学debug,才发现大问题,我的程序是通过query查到最小值,然后通过值返回编号,具体是通过查询一个tr数组(反向数组)返回去查编号

但是我的程序在不合法的时候会返回-1,这样会导致查询到数组的-1位置

但是神奇的是我没检查程序直接交了,竟然过了,后来重新试了几发,C++20 14 开不开O2都试过了,都能过

但是现在本地dev连样例都过不了了(我改完之后蜜汁自信,没对样例直接交了),但是洛谷上面AC,不知道是什么情况

有知道原理的大犇能够解答一下吗?

代码我放到下面,需要的话可以阅读:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 5;
const int MAXM = 1e5 ; 
int n,m;
int T[MAXN],lch[MAXN],rch[MAXN],nt;
int pri[MAXN],root[MAXN],tr[MAXN];
int confa[MAXN];
int Q,a,b;
char op;
void push_up(int p){T[p]=T[lch[p]]+T[rch[p]];}
int find(int x){return x==confa[x]?x:confa[x]=find(confa[x]);}
void change(int pos,int x,int &p,int s=1,int t=n){
	if(!p)p=++nt;
	if(s==t)return T[p]=x,void();
	int mid=(s+t)>>1;
	if(pos<=mid)change(pos,x,lch[p],s,mid);
	else change(pos,x,rch[p],mid+1,t);
	push_up(p);
}
int merge(int p1,int p2){
	if(!(p1&&p2))return p1|p2;
	T[p1]+=T[p2];
	lch[p1]=merge(lch[p1],lch[p2]);
	rch[p1]=merge(rch[p1],rch[p2]);
	return p1;
}
int query(int k,int p,int s=1,int t=n){
	if(!p)return -1;
	if(s==t)return s;
	int mid=(s+t)>>1;
	if(T[lch[p]]>=k)return query(k,lch[p],s,mid);
	else return query(k-T[lch[p]],rch[p],mid+1,t);
}
int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&pri[i]),change(pri[i],1,root[i]),confa[i]=i,tr[pri[i]]=i;
	for(int i=1;i<=m;i++){
		scanf("%d %d",&a,&b);
		merge(root[find(a)],root[find(b)]);
		confa[find(b)]=find(a);
	}
	scanf("%d",&Q);
	while(Q--){
		scanf(" %c %d %d",&op,&a,&b);
		if(op=='Q')printf("%d\n",tr[query(b,root[find(a)])]);
		else merge(root[find(a)],root[find(b)]),confa[find(b)]=find(a);
	}
	return 0;
}
2023/10/5 11:39
加载中...