这题远没有它看起来那么可怕..
容易发现当n>70时a[n]就已远大于1e9,此时和a[n]有关的差只有a[n]-a[n-1]在n为偶数的情况下在1e9之内
于是打个70的表,如果当前的x在打表时没出现,就二分找已经出现的差有多少个
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e9
using namespace std;
const int maxn = 110000;
int n;
ll a[maxn];
struct node
{
int p,q;
ll x;
};
inline bool operator <(const node x,const node y){return x.x<y.x;}
set<node>S;
set<node>::iterator it,it1;
ll t[maxn]; int tp;
int main()
{
a[1]=1; S.insert((node){1,1,0});
a[2]=2; S.insert((node){2,1,1}); it1=S.find((node){2,1,1}); t[++tp]=1;
ll now=1; int u=70;
for(int i=3;i<=u;i++)
{
if(i&1)
{
a[i]=a[i-1]*2ll;
for(int j=i-1;j>=1;j--)
{
node tmp=(node){i,j,a[i]-a[j]};
it=S.find(tmp);
if(it==S.end()) S.insert(tmp),t[++tp]=tmp.x;
}
}
else
{
it=it1;
while(it!=S.end())
it=S.find((node){0,0,++now});
a[i]=a[i-1]+now;
for(int j=i-1;j>=1;j--)
{
node tmp=(node){i,j,a[i]-a[j]};
it=S.find(tmp);
if(it==S.end()) S.insert(tmp),t[++tp]=tmp.x;
}
}
}
/*for(int i=1;i<=u;i++) printf("%lld\n",a[i]);
puts(""); puts("");puts("");puts("");puts("");
for(int i=1;i<=tp;i++) printf("%lld\n",t[i]);*/
sort(t+1,t+tp+1);
scanf("%d",&n);
while(n--)
{
ll k; scanf("%lld",&k);
it=S.find((node){0,0,k});
if(it==S.end())
{
int l=1,r=tp;
while(l<=r)
{
int mid=l+r>>1;
if(t[mid]<k) l=mid+1;
else r=mid-1;
}l--;
ll p=u+(k-l)*2ll;
printf("%lld %lld\n",p,p-1);
}
else
{
printf("%d %d\n",(*it).p,(*it).q);
}
}
return 0;
}