【做题记录】Luogu 1366 有序表的合并

Luogu 1366 有序表的合并

link

做法:双指针
注意:这两个数列都有序

代码:

#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cctype>
typedef long long LL;
typedef unsigned long long ULL;
namespace FastIo{
    typedef __uint128_t ULLL;
    static char buf[100000],*p1=buf,*p2=buf,fw[100000],*pw=fw;
    #define gc p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++
    inline void pc(const char &ch){
    	if(pw-fw==100000)fwrite(fw,1,100000,stdout),pw=fw;
    	*pw++=ch;
	}
    #define fsh fwrite(fw,1,pw-fw,stdout),pw=fw 
	struct FastMod{
        FastMod(ULL b):b(b),m(ULL((ULLL(1)<<64)/b)){}
        ULL reduce(ULL a){
            ULL q=(ULL)((ULLL(m)*a)>>64);
            ULL r=a-q*b;
            return r>=b?r-b:r;
        }
        ULL b,m;
    }HPOP(10);
    struct QIO{
    	char ch;
    	int st[40];
    	template<class T>inline void read(T &x){
    		x=0,ch=gc;
    		while(!isdigit(ch))ch=gc;
    		while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=gc;}
		}
		template<class T>inline void write(T a){
			do{st[++st[0]]=HPOP.reduce(a);a/=10;}while(a);
			while(st[0])pc(st[st[0]--]^48);
			pc('\n');
		}
	}qrw;
}
using namespace FastIo;
#define NUMBER1 10000000
#define P(A) A=-~A
#define fione(i,a,b) for(register int i=a;i<=b;P(i))
ULL a[NUMBER1+5],b[NUMBER1+5],ans;
signed main(){
	int T,n,m,p,cnt;
	qrw.read(T);
	while(T--){
		p=1,ans=0;
		qrw.read(n);
		qrw.read(m);
		fione(i,1,n)qrw.read(a[i]);
		fione(i,1,m)qrw.read(b[i]);
		fione(i,1,n){
			cnt=0;
			while(a[i]>=b[p]&&p<=m){
				if(a[i]==b[p])P(cnt);
				P(p);
			}
			ans^=cnt;
		}
		qrw.write(ans);
	}
	fsh;
    exit(0);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 本题要求实现折半查找的递归查找操作。例如对于下图的有序: ![image](https://cdn.luogu.com.cn/upload/image_hosting/s4g4d4l4.png) 现在要查找元素7。首先找到有序的中间位置的元素3,由于7>3,所以应该在右半边查找。再对右半边的有序进行递归查找,直到找到元素为止。 ### 回答2: 折半查找,也叫二分查找,是一种常见的查找算法。它利用有序的特性,在查找过程中通过逐步缩小查找范围,最终找到目标元素。它的查找效率高,时间复杂度为O(logn)。 下面是折半查找的递归查找操作的实现步骤: 1.设定查找范围的上下限,即low和high,初始时low=0,high=n-1,其中n为有序的长度。 2.计算中间位置mid=(low+high)/2,为了避免low+high过大导致溢出,可以使用mid=low+(high-low)/2。 3.比较中间位置的元素与目标元素的大小。 如果中间位置的元素小于目标元素,则目标元素只可能在mid的右边。此时对mid+1到high范围进行递归查找。 如果中间位置的元素大于目标元素,则目标元素只可能在mid的左边。此时对low到mid-1范围进行递归查找。 如果中间位置的元素等于目标元素,则查找成功。 4.重复执行步骤2~3,直到找到目标元素或者low>high。 下面以样例数据为例进行递归查找操作的演示: 目标元素为9。初始时,low=0,high=9,mid=4。a[mid]=6<9,目标元素只可能在mid的右边。因此进入第二次查找操作,low=5,high=9,mid=7。a[mid]=9,查找成功,返回mid=7。 目标元素为4。初始时,low=0,high=9,mid=4。a[mid]=6>4,目标元素只可能在mid的左边。因此进入第二次查找操作,low=0,high=3,mid=1。a[mid]=4,查找成功,返回mid=1。 目标元素为10。初始时,low=0,high=9,mid=4。a[mid]=6<10,目标元素只可能在mid的右边。因此进入第二次查找操作,low=5,high=9,mid=7。a[mid]=9<10,目标元素只可能在mid的右边。因此进入第三次查找操作,low=8,high=9,mid=8。a[mid]=10,查找成功,返回mid=8。 总之,折半查找是一种高效的查找算法,在大数据量的情况下能够快速定位目标元素的位置。要实现递归查找操作,只需要熟悉上述步骤,理解递归调用的原理即可。 ### 回答3: 折半查找算法是一种高效的查找算法,也称为二分查找算法。适用于有序数组,目的是在数组中查找某个元素。其基本思想是将数组分成两个部分,判断待查找元素与数组中间元素的大小关系,如果待查找元素小于中间元素,那么继续在左侧查找,否则在右侧查找。递归查找操作,就是在每个子数组中,重复以上过程,直到找到为止或者查找范围缩小为0。 在实现折半查找的递归查找操作时,可以使用递归函数实现。首先需要找到中点,将待查找元素与中点进行比较,然后根据比较结果,更新左右边界,继续递归调用函数查找左右两个子数组。 在本题所给出的有序中,我们可以设定左右边界,然后定义递归函数BinarySearch进行查找,实现代码如下: ```python def BinarySearch(arr, l, r, x): if r >= l: mid = int(l + (r - l) / 2) # 如果元素小于中点,那么在左侧查找 if arr[mid] > x: return BinarySearch(arr, l, mid - 1, x) # 如果元素大于中点,那么在右侧查找 elif arr[mid] < x: return BinarySearch(arr, mid + 1, r, x) # 如果元素正好等于中点,那么返回中点的索引 else: return mid # 如果元素不存在于数组中,那么返回-1 else: return -1 ``` 在使用此函数进行查找时,需要传入有序,以及待查找元素在列中的左右边界。我们可以先将左边界设为0,右边界设为列的长度-1,然后调用此函数进行查找。如果函数返回值不为-1,那么示找到了该元素,并返回元素的索引;如果返回值为-1,那么示列中不存在该元素。 总之,折半查找递归查找操作是一种高效的查找算法,在有序数组中应用广泛,可以很好地解决大规模数据查找问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值