Skip to main content
Original210 words1 min

题解:P1366 有序表的合并

Summary

两个有序表 a 和 b,对 a 中每个元素统计它在 b 中出现的次数,最后求所有次数的异或和。做法是双指针:随着 a 递增同步向后推进 b 的左右边界,左边界停在第一个等于当前值的位置,右边界停在第一个大于它的位置,两者之差即出现次数。整体一遍线性扫描。

参考资料​

解题思路​

初始时,令左右边界 l=r=1l=r=1。

对于每个元素 aia_i,执行以下操作:

  1. 将区间左边界 ll 从 rr 开始向后枚举,直到 bl=aib_l=a_i(l≤ml\le m),说明 blb_l 是第一个等于 aia_i 的元素。
  2. 将区间右边界 rr 从 ll 开始向后枚举,直到 br≠aib_r\ne a_i(r≤mr\le m),说明 brb_r 是第一个不等于 aia_i 的元素。
  3. 此时 r−lr-l 即为 aia_i 出现的个数。

最后求出所有数的异或和。

参考代码​

477 Bcpp
#include <bits/stdc++.h>
using namespace std;

using ull=unsigned long long;
const int N=10000005;
ull a[N],b[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++)cin>>b[i];
int l=1,r=1,ans=0;
for(int i=1;i<=n;i++)
{
l=r;
while(l<=m&&b[l]<a[i])l++;
r=l;
while(r<=m&&b[r]==a[i])r++;
ans^=r-l;
}
cout<<ans<<'\n';
}
return 0;
}