L. Ray in the tube(思维&暴力)

L. Ray in the tube(思维&暴力)

思路:思维+暴力。

记: A , B A,B 的横坐标距离为 x x

1.当 x x 为奇数时,显然 x = 1 x=1 包含所有奇数的情况。

2.当 x x 为偶数时,因为任何偶数质因数分解都可分解为: 2 k 1 × p 2 k 2 p m k m 2^{k_1}\times p_2^{k_2}\dots p_m^{k_m}

所以任何偶数都可以被 2 k 1 2^{k_1} 替代。

即我们只需枚举 2 0 = 1 , 2 1 , , 2 k , ( 2 k 1 e 9 ) 2^0=1,2^1,\dots,2^k,(2^k\leq 1e9) 即可。

对于一个界面我们只需将所有的横坐标对 2 x 2x 取模,取模后的相等的数是可以等价的,

对于另一个界面我们只需将所有横坐标 + x +x 后再对 2 x 2x 取模,因为两个界面的可到达点是相距 x x 的。

这样我们只需求出现次数最多的横坐标即可。

时间复杂度: O ( ( n + m ) l o g ( 1 e 9 ) ) O((n+m)log(1e9))

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int a[N],b[N],c[N<<1];
int main(){	
	int n,m,h,ans=2; 
	scanf("%d%d",&n,&h);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	scanf("%d%d",&m,&h);
	c[n+m+1]=1e9+1; 
	for(int i=1;i<=m;i++) scanf("%d",&b[i]);
	for(int i=1;i<=1e9;i<<=1){
		int mod=(i<<1);
		for(int j=1;j<=n;j++) c[j]=a[j]%mod;
		for(int j=1;j<=m;j++) c[j+n]=(b[j]+i)%mod;
		sort(c+1,c+n+m+1);
		for(int j=1,pre=0;j<=n+m;j++){
			 if(c[j]!=c[j+1]){
			 	 ans=max(ans,j-pre);
			 	 pre=j;
			 }
		}
	}
	printf("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107519738