#544 (Div. 3) D. Zero Quantity Maximization

本文深入探讨了一种名为零数量最大化的算法问题,旨在通过优化参数d,使两个数组经特定运算后生成的新数组中零元素的数量达到最大。文章详细介绍了算法的实现思路,包括如何处理精度问题,利用gcd函数进行数据简化,以及使用map进行统计,最终得出最优解。

D. Zero Quantity Maximization

time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output


You are given two arrays a and b, each contains nnn integers.

You want to create a new array ccc as follows: choose some real (i.e. not necessarily integer) number d, and then for every i∈[1,n]i\in[1,n]i[1,n] let ci:=d⋅ai+bic_i:=d⋅a_i+b_ici:=dai+bi.

Your goal is to maximize the number of zeroes in array ccc. What is the largest possible answer, if you choose ddd optimally?

Input

The first line contains one integer nnn (1≤n≤2⋅105)(1≤n≤2⋅10^5)(1n2105) — the number of elements in both arrays.

The second line contains n
integers a1,a2,...,an(−109≤ai≤109).a_1, a_2, ..., a_n (−10^9≤ai≤10^9).a1,a2,...,an(109ai109).

The third line contains nnn
integers b1,b2,...,bn(−109≤bi≤109).b_1, b_2, ..., b_n (−10^9≤bi≤10^9).b1,b2,...,bn(109bi109).

Output

Print one integer — the maximum number of zeroes in array ccc, if you choose d optimally.

Examples

Input
3
13 37 39
1 2 3
Output
2

题目大意

给你数组A和数组B, 让你找到任意实数d使得,尽可能多的d⋅ai+bi=0d⋅a_i+b_i = 0dai+bi=0.成立。
本来我是直接用bib_ibi除以aia_iai, 得到一个doubledoubledouble, 然后用mapmapmap计数。但是精度问题,不可以这样做。
所以必须想办法保存这个状态。观察,要使d⋅ai+bi=0d⋅a_i+b_i = 0dai+bi=0成立,固定d不变。 那么对于d⋅ai⋅k+bi⋅k=0,kd⋅a_i⋅k+b_i⋅k = 0,kdaik+bik=0k属于任意数都成立。
从这里我们看出来gcdgcdgcd了,将ai、bia_i、b_iaibi除以gcdgcdgcd后组合成pairpairpair,再用mapmapmap统计即可。

注意对于每组ai、bia_i、b_iaibi有四种情况

  1. ai=0,bi≠0a_i = 0,b_i \ne 0ai=0bi̸=0 此时,数据无效
  2. ai=0,bi=0a_i = 0,b_i = 0ai=0bi=0 此时,ddd 可以为任意数,一定可以入选
  3. ai≠0,bi=0a_i \ne 0,b_i = 0ai̸=0bi=0 此时,ddd 仅可为 000
  4. ai≠0,bi≠0a_i \ne 0,b_i \ne 0ai̸=0bi̸=0 此时,需要除以最小公倍数,进行统计
#include<bits/stdc++.h>
using namespace std;
const int MAX = 200005;
int a[MAX];
int ans; 
int s, t;
map<pair<int, int>, int> mp;
int gcd(int x, int y){
	return !(x%y) ? y : gcd(y, x % y);
}
int main(){
	int n; cin >> n;
	ans = s = t = 0;
	for(int i = 0; i < n; i++){
		cin >> a[i];
	}
	int temp;
	for(int i = 0; i < n; i++){
		cin >> temp;
		if(!temp && !a[i]) s++;
		else if(!temp) t++;
		else if(!a[i]) continue;
		else{
			if(a[i] < 0){
				a[i] = -a[i];
				temp = -temp;
			}
			int gd = gcd(a[i], abs(temp));
			pair<int, int> p = make_pair(a[i]/gd, temp/gd);
			mp[p]++;
			ans = max(ans, mp[p]); 
		}
	}
	ans = max(t, ans);
	cout << ans + s << endl;
	
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值