“蔚来杯“2022牛客暑期多校训练营10-I Yet Another FFT Problem?

发布于:2023-01-10 ⋅ 阅读:(464) ⋅ 点赞:(0)

原题题面:https://ac.nowcoder.com/acm/contest/33195/I

题目大意

给定两个整数序列 A = [ a 1 , a 2 , ⋅ ⋅ ⋅ , a n ] ( 2 ≤ n ≤ 1 0 6 , 0 ≤ a i ≤ 1 0 7 ) , B = [ b 1 , b 2 , ⋅ ⋅ ⋅ , b m ] ( 2 ≤ m ≤ 1 0 6 , 0 ≤ b i ≤ 1 0 7 ) A=[a_1,a_2,···,a_n](2\le n\le 10^6,0\le a_i\le 10^7),B=[b_1,b_2,···,b_m](2\le m\le 10^6,0\le b_i\le 10^7) A=[a1,a2,⋅⋅⋅,an](2n106,0ai107),B=[b1,b2,⋅⋅⋅,bm](2m106,0bi107),求是否存在 1 ≤ i , j ≤ n , 1 ≤ k , l ≤ m 1\le i,j\le n,1\le k,l\le m 1i,jn,1k,lm,满足 i ≠ j , k ≠ l , ∣ a i − a j ∣ = ∣ b k − b l ∣ i\neq j,k\neq l,|a_i-a_j|=|b_k-b_l| i=j,k=l,aiaj=bkbl

解题思路

使得 a i ≥ a j , b k ≥ b l a_i\ge a_j,b_k\ge b_l aiaj,bkbl,原式可得 a i + b l = a j + b k a_i+b_l=a_j+b_k ai+bl=aj+bk,由于 0 ≤ a i , a j , b k , b l ≤ 1 0 7 0\le a_i,a_j,b_k,b_l\le10^7 0ai,aj,bk,bl107,所以 0 ≤ a i + b l , a j + b k ≤ 2 × 1 0 7 0\le a_i+b_l,a_j+b_k\le2\times10^7 0ai+bl,aj+bk2×107,若 i ≠ j , a i ≠ a j , b i ≠ b j i\neq j,a_i\neq a_j,b_i\neq b_j i=j,ai=aj,bi=bj,根据鸽巢原理,枚举最多进行 2 × 1 0 7 + 1 2\times10^7+1 2×107+1次,可以放心大胆地枚举。若有重复,进行去重,对于每个 a i = x a_i=x ai=x b j = y b_j=y bj=y最多存两次,仍然能过。

代码实现

#include<bits/stdc++.h>
using namespace std;
template <class T> inline void read(T&x){
	char c,f=' ';
	while(!isdigit(c=getchar()))f=c;
	x=c^48;
	while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+(c^48);
	if(f=='-')x=-x;
}
const int N=1e6+5,M=2e7+5;
int n,m,A[N],B[N],a,b[M],p1[M],p2[M],cnt1[M],cnt2[M],x,y;
pair<int,int>ma[M];
int main(){
	read(n),read(m);
	for(int i=1;i<=n;i++){
		read(a);
		if(cnt1[a]>1)continue;
        A[++x]=a;
		p1[x]=i,cnt1[a]++;
	}
	for(int i=1;i<=m;i++){
		read(a);
		if(cnt2[a]>1)continue;
        B[++y]=a;
		p2[y]=i;cnt2[a]++;
	}
	for(int i=1;i<=x;i++)
	for(int j=1;j<=y;j++){
		int k=A[i]+B[j];
		int u=ma[k].first,v=ma[k].second;
		if(b[k]&&i!=u&&j!=v){
			cout<<p1[u]<<' '<<p1[i]<<' '<<p2[v]<<' '<<p2[j]<<'\n';
			return 0;
		}
        b[k]=1;
		if(i!=u&&j!=v)ma[k]=make_pair(i,j);
	}
	cout<<-1;
}

网站公告

今日签到

点亮在社区的每一天
去签到