https://codeforces.com/contest/1469/problem/D
This observation found a better strategy
We choose a base c, and then let n/(n/c), (n/c)/(n/c/c)... and so on, turn these numbers into c, and then use c again at the end Turn them into 1, and finally use 2 to turn c into 1, then there will be 2 and 2 in the end, and the others are 1.
For other numbers that are not considered in the middle, we first let them all /n become 1
So for the numbers 3-n, only c must keep him /2, and then the numbers n/c and n/c/c must first change to c and then change to 1. The other numbers change to 1 at a time.
So this question is essentially to minimize log_c{n}+log_2{c}
People with a solid foundation in mathematics will do it right away. The uncle next door who is in his 20s who is still doing basic mathematics and science has been studying for a long time, but don’t learn from me.
Finally, try to find that c=8 is feasible under n=2e5
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,k,cnt,tot,cas;
int a[maxl];
bool vis[maxl];
char s[maxl];
typedef pair<int,int> p;
vector<p> ans,ans2;
inline void prework()
{
scanf("%d",&n);
// n=2e5;
for(int i=1;i<=n;i++)
vis[i]=false;
ans.clear();
int c=8,now=n,nxt;cnt=0;
if(n<c)
{
for(int i=3;i<n;i++)
ans.push_back({i,n});
now=n;
while(now>1)
now=now/2+(int)(now%2!=0),ans.push_back({n,2});
return;
}
while(1)
{
if(now<=c)
break;
vis[now]=true;
a[++cnt]=now;
nxt=now/c;
if(now%c!=0)
nxt+=1;
now=nxt;
}
a[++cnt]=c;
vis[c]=true;
for(int i=3;i<n;i++)
if(!vis[i])
ans.push_back({i,n});
for(int i=1;i<cnt;i++)
ans.push_back({a[i],a[i+1]});
for(int i=1;i<cnt;i++)
ans.push_back({a[i],c});
now=c;
while(now>1)
now=now/2+(int)(now%2!=0),ans.push_back({c,2});
}
inline void mainwork()
{
}
inline void print()
{
tot=ans.size();
printf("%d\n",tot);
for(p d:ans)
printf("%d %d\n",d.first,d.second);
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}