P8814 [CSP-J 2022] 解密
// ni = pi * qi
// ei * di = pi * qi - pi - qi + 2
// ei * di = ni - pi - qi + 2
// pi + qi = ni - ei * di + 2
// pi * qi = ni
// pi + qi = m
//
// pi * qi = 770
// pi + qi = 770 - 77*5 + 2
// m<=10^9
// m = 10000
// m/2 = 5000 5000*5000 = 25000000
// 10000 = 25000000 - ei * di + 2 = 24990002
// 24990002 = 12495001 * 2
/*
1
25000000 12495001 2 //相同
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
int k;
ll m, ni, di, ei, pi, qi;
int main(){
scanf("%d",&k);
for(int i = 1; i <= k; i++){
scanf("%lld%lld%lld",&ni,&di,&ei);
m = ni - ei * di + 2;
// cout<<m/2<<endl;
bool fl = 0 ;
if(m % 2 == 0 && (m / 2) * (m / 2) == ni){
fl = 1; printf("%lld %lld\n", m/2, m/2);
continue;
}
if(fl == 1) continue;
for(ll pi = 1; pi * pi <= ni; pi++){//pi小
qi = m - pi;
if(pi * qi == ni){
fl = 1; printf("%lld %lld\n", pi, qi);
break;
}
}
if(!fl) printf("NO\n");
}
return 0;
}
温皓程二分:
x(m-x) = n
设 f(x) = -x^2 + mx
求导,得到-2x+m =0 说明是一个波峰或者波谷, 2x=m, x = m/2, 是峰或者谷
x<= m/2 有单调性,去二分它
#include<bits/stdc++.h>
using namespace std;
int T;
long long n,e,d;
int main(){
// freopen("decode.in","r",stdin);
// freopen("decode.out","w",stdout);
scanf("%d",&T);
while(T--){
bool flag=0;
scanf("%lld%lld%lld",&n,&e,&d);
long long jj=e*d;
long long cha=n-jj+2;
long long l=1,r=cha/2;
while(l<r){
long long mid=(l+r+1)/2;
if(mid*(cha-mid)>n) r=mid-1;
else l=mid;
}
if(l*(cha-l)==n) printf("%lld %lld\n",min(l,(cha-l)),max(l,(cha-l)));
else printf("NO\n");
}
return 0;
}