Problem Description
一开始有 nnn 个数,他们按 1…n1…n1…n 的顺序排列,要求交换最多 mmm 对数字(同一个数字可以参与多次交换),使得逆序对数目最大。
对于一个序列 AAA,如果存在正整数 i,ji, ji,j 使得 1≤i
Input
第一行一个正整数 test (1≤test≤100000)test~(1 \leq test \leq 100000)test (1≤test≤100000) 表示数据组数。
对于每组数据,一行两个整数 n,m (1≤n≤1000000,0≤m≤1000000)n,m~(1 \leq n \leq 1000000, 0 \leq m \leq 1000000)n,m (1≤n≤1000000,0≤m≤1000000) 表示数字个数和最多可以交换的数字对数。
Output
对于每组数据,一行一个整数表示答案。
Sample Input
6
1 1
2 0
2 1
3 1
4 1
4 2
Sample Output
0
0
1
3
5
6
这是一道很简单的题,
思路 : 对于一个长度为n
的有序列1,2,3,4,5,...n
可以发现
0
,如1 2 3 4
4 3 2 1
1
和n
一定能的到最多的逆序对个数(n-1)+(n-2)
个逆序对,2
和n-1
一定最优,第三次交换3
和n-2
一定最优例如 : 最后一组样例
开始时 : 1 2 3 4
交换0
次 逆序对个数0
对
m=1时 : 4 2 3 1
交换1
次 逆序对增加了(4-1)+(4-2)
对
m=2时 : 4 3 2 1
交换2
次 逆序对增加了(2-1)+(2-2)
对
m=3时 : 4 3 2 1
交换0
次 当前已经是逆序数对最多的排列了,无需交换
…
观察到1到10
的m
从0增大到n/2
服从如下表
10 : 17 13 9 5 1
9 : 15 11 7 3
8 : 13 9 5 1
7 : 11 7 3
6 : 9 5 1
5 : 7 3
4 : 5 1
3 : 3
2 : 1
1 :
#define debug
#ifdef debug
#include
#include "/home/majiao/mb.h"
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXN ((int)1e5+7)
#define ll long long
#define int long long
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for(int i=lef; i<=rig; i++)
#define forj(lef, rig) for(int j=lef; j<=rig; j++)
#define fork(lef, rig) for(int k=lef; k<=rig; k++)
#define QAQ (0)
using namespace std;
#ifdef debug
#define show(x...) \
do { \
cout << "\033[31;1m " << #x << " -> "; \
err(x); \
} while (0)
#else
#define show(x...)
#endif
void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }
namespace FastIO {
char print_f[105];
void read() { }
void print() { putchar('\n'); }
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {
x = 0;
char ch = getchar();
ll f = 1;
while (!isdigit(ch)) {
if (ch == '-') f *= -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - 48;
ch = getchar();
}
x *= f;
read(oth...);
}
template <typename T>
inline void put(T x) {
if(x==0) { putchar('0'); putchar('\n'); return; }
if(x<0) { putchar('-'); x = -x; }
int num=0;
char ch[128];
while(x) ch[++num] = x % 10 + '0', x /= 10;
while(num) putchar(ch[num--]);
putchar('\n');
}
}; // namespace FastIO
using FastIO::read;
using FastIO::put;
int n, m, Q, K;
/**
10 : 17 13 9 5 1
9 : 15 11 7 3
8 : 13 9 5 1
7 : 11 7 3
6 : 9 5 1
5 : 7 3
4 : 5 1
3 : 3
2 : 1
1 :
*/
signed main() {
#ifdef debug
freopen("test", "r", stdin);
// freopen("out_main", "w", stdout);
clock_t stime = clock();
#endif
read(Q);
while(Q--) {
read(n, m);
if(m == 0 || (n == 1)) {
printf("0\n");
continue ;
}
int N = n / 2;
if(m >= N) {
m = n / 2;
}
// m = (m % (n/2) == 0 ? (n/2) : (m%(n/2)));
int ans = n*2 - 3;
m --;
int tmp = ans * m;
tmp -= (m*4 + (m*(m-1))/2*4);
ans += tmp ;
// show(ans, tmp, m);
printf("%lld\n", ans);
}
#if 0
for(n=10; n>=1; n--) {
printf("%d : ", n);
for(int i=n; (i-2)>=0; i-=2) {
printf("%d ", i*2-3);
}
printf("\n");
}
#endif
#ifdef debug
clock_t etime = clock();
printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif
return 0;
}