## 2020 wannafly camp 补题 day1

B. 密码学

1H. 最大公约数

gcd(m*k,y)!=k，所以如果有数是k的素数倍，那么y也一定是这个素数的倍数。

F. 乘法

```#include<iostream>
#include<cstdio>
#include<cstring>
#include<bits/stdc++.h>
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
ll a[maxn],b[maxn];
ll a1[maxn],a2[maxn],b1[maxn],b2[maxn];
ll tota1=0,tota2=0,totb1=0,totb2=0,zera=0,zerb=0;
ll n,m,k;
bool check(ll x){
ll sum=0;
if(x<=0){
sum+=tota1*totb1+tota2*totb2+zera*m+zerb*n-zera*zerb;
//        printf("sum=%lld\n",sum);
if(x==0) return sum>=k;
if(sum>=k) return true;
x=-x;
for(int i=1;i<=tota1&&totb2;i++){
ll t=upper_bound(b2+1,b2+1+totb2,x/a1[i])-b2;
if(b2[t]>x/a1[i]||t>totb2) t--;
sum+=t;
//            printf("aa i=%d sum=%lld t=%d %d\n",i,sum,t,totb2);
}
for(int i=1;i<=tota2&&totb1;i++){
ll t=upper_bound(b1+1,b1+1+totb1,x/a2[i])-b1;
//            printf("t=%d\n",t);
if(b1[t]>x/a2[i]||t>totb1) t--;
sum+=t;
//            printf("i=%d sum=%lld t=%d\n",i,sum,t);

}
//        printf("x=%lld sum=%lld\n",x,sum);
return sum>=k;
}
for(int i=1;i<=tota1&&totb1;i++){
ll val=x/a1[i];
if(x%a1[i]) val++;
int t=lower_bound(b1+1,b1+1+totb1,val)-b1;
sum+=totb1-t+1;
}
for(int i=1;i<=tota2&&totb2;i++){
ll val=x/a2[i];
if(x%a2[i]) val++;
int t=lower_bound(b2+1,b2+1+totb2,val)-b2;
sum+=totb2-t+1;
}
return sum>=k;
}
int main(){
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=m;i++) scanf("%lld",&b[i]);
for(int i=1;i<=n;i++){
if(a[i]<0) a1[++tota1]=-a[i];
else if(a[i]>0) a2[++tota2]=a[i];
else zera++;
}
for(int i=1;i<=m;i++){
if(b[i]<0) b1[++totb1]=-b[i];
else if(b[i]>0) b2[++totb2]=b[i];
else zerb++;
}
sort(a1+1,a1+1+tota1);
sort(a2+1,a2+1+tota2);
sort(b1+1,b1+1+totb1);
sort(b2+1,b2+1+totb2);
//    printf("%d %d %d %d\n",tota1,tota2,totb1,totb2);
ll l=-inf64,r=inf64,ans=0;
while(l<=r){
ll mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%lld\n",ans);
return 0;
}
/*
1 2 2
2
-3 -3

*/```
F