对于n=sum[i]+sum[j],可以夹逼寻找,时间复杂度O(n)。
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=15715;
int sum[N],goal;
void solve(int n){//夹逼寻找两个数的组成,O(n)
int left=1,right=lower_bound(sum,sum+N,n)-sum,t;
while(left<=right){//夹逼定理
t=sum[right]+sum[left];
if(t>n)
right--;
else if(t<n)
left++;
else{
goal=1;
printf("%d %d",left,right);
return;
}
}
}
int main(){
for(int i=1;i<N;i++){
sum[i]=sum[i-1]+i;
/*if(sum[i]>123456789){
printf("%d\n",i);break;}*/
}
int tt,n;
cin>>tt;
while(tt--){
cin>>n;
goal=0;
int p1=lower_bound(sum,sum+N,n)-sum;
if(sum[p1]==n){// 1个
printf("%d\n",p1);
goal=1;
continue;
}
solve(n);//2个
if(goal){
printf("\n");
continue;
}
for(int i=1;i<N;i++){//分离出1个+2个=3个
solve(n-sum[i]);
if(goal==1){
printf(" %d\n",i);
break;
}
}
}
}