题目链接:https://codeforces.com/contest/1474/problem/E
开始以为答案是 (1^2 + 2 ^ 2 + ... + (n - 1) ^ 2)
看题解以后发现没有这么简单。。
因为每次交换必定会让一个位置还原,所以每个位置都要尽量和当前没有还原位置中的最远的位置交换,
也就是把首位两个位置放到最后再还原
最后的贡献为 $$(n-1)^2 + 2 * (n-2) ^ 2 + ... + t * 1 ^ 2$$
其中 (t) 根据 (n) 的奇偶性决定
构造方案就按照交换顺序反向构造即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
#define mp make_pair
const int maxn = 100010;
int T, n;
int a[maxn], to[maxn];
ll ans = 0;
vector<P> pa;
ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
int main(){
T = read();
while(T--){
pa.clear();
ans = 0;
n = read();
int cnt = n - 1, delta = 2;
for(int i = 1 ; i <= n ; ++i) a[i] = i;
--cnt; swap(a[1], a[n]);
pa.push_back(mp(1, n));
while(cnt){
--cnt;
swap(a[1], a[n - delta + 1]);
pa.push_back(mp(n - delta + 1, 1));
if(cnt){
--cnt;
swap(a[n], a[delta]);
pa.push_back(mp(delta, n));
}
++delta;
}
ans = 1ll * (n - 1) * (n - 1);
int tot = n - 2;
cnt = n - 2;
while(cnt){
--cnt;
ans += 1ll * tot * tot;
if(cnt){
--cnt;
ans += 1ll * tot * tot;
}
--tot;
}
printf("%lld
", ans);
for(int i = 1 ; i <= n ; ++i) printf("%d ", a[i]); printf("
");
printf("%d
", n - 1);
reverse(pa.begin(), pa.end());
for(auto p: pa){
printf("%d %d
", p.first, p.second);
}
}
return 0;
}