Ceil Divisions
D. Ceil Divisions
You have an array \(a_1,a_2,…,a_n\)where ai=i.
In one step, you can choose two indices x and y (x≠y) and set \(a_x=\lceil{\frac{a_x}{a_y}}\rceil\)(ceiling function).
Your goal is to make array a consist of n−1 ones and 1 two in no more than n+5 steps. Note that you don't have to minimize the number of steps.
Input
The first line contains a single integer t \((1\leq t\leq 1000)\) — the number of test cases.
The first and only line of each test case contains the single integer n\((3\leq n \leq 2⋅10^5)\) — the length of array a.
It's guaranteed that the sum of n over test cases doesn't exceed 2⋅105.
Output
For each test case, print the sequence of operations that will make a as n−1 ones and 1 two in the following format: firstly, print one integer m \((m\leq n+5m\leq n+5)\) — the number of operations; next print m pairs of integers x and y \((1\leq x,y\leq n; x≠y)\) (x may be greater or less than y) — the indices of the corresponding operation.
It can be proven that for the given constraints it's always possible to find a correct sequence of operations.
Example
input
2
3
4
output
2
3 2
3 2
3
3 4
4 2
4 2
Note
In the first test case, you have array a=[1,2,3]. For example, you can do the following:
- choose 3, 2: \(a_3=\lceil{\frac{a_3}{a_2}}\rceil=2\) and array a=[1,2,2];
- choose 3, 2: \(a_3=\lceil{\frac{a_3}{a_2}}\rceil=1\) and array a=[1,2,1].
You've got array with 2 ones and 1 two in 2 steps.
一开始想的是取log2(n)个或者是log10(n)个不除,然后其余的除以n,全变成1 ,用n除以(n+1)/2等等,但是总是多几次
正解:
n用16(或15等)除若干次,变为1,16再用2除以4次,变成1
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=108,mod=1e9+7,inf=0x3f3f3f3f;
int main(){
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
if(n<=16){
printf("%d\n",n-3+(int)ceil(log2(n)));
for(int i=3;i<n;++i)printf("%d %d\n",i,n);
for(int i=n;i>1;i=(i+1)/2)
printf("%d 2\n",n);
}else{
printf("%d\n",n-4+4+(int)ceil(log2(n)/4.0));
for(int i=3;i<16;++i)printf("%d %d\n",i,n);
for(int i=17;i<n;++i)printf("%d %d\n",i,n);
for(int i=n;i>1;i=(i+15)/16)printf("%d 16\n",n);
for(int i=0;i<4;++i)printf("16 2\n");
}
}
return 0;
}