Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:
For an undirected graph G with n nodes and m edges, we can define the distance between (i,j) ( dist(i,j) ) as the length of the shortest path between i and j . The length of a path is equal to the number of the edges on it. Specially, if there are no path between i and j , we make dist(i,j) equal to n .
Then, we can define the weight of the graph G ( wG ) as ∑ni=1∑nj=1dist(i,j) .
Now, Yuta has n nodes, and he wants to choose no more than m pairs of nodes (i,j)(i≠j) and then link edges between each pair. In this way, he can get an undirected graph G with n nodes and no more than m edges.
Yuta wants to know the minimal value of wG .
It is too difficult for Rikka. Can you help her?
In the sample, Yuta can choose (1,2),(1,4),(2,4),(2,3),(3,4) .
For an undirected graph G with n nodes and m edges, we can define the distance between (i,j) ( dist(i,j) ) as the length of the shortest path between i and j . The length of a path is equal to the number of the edges on it. Specially, if there are no path between i and j , we make dist(i,j) equal to n .
Then, we can define the weight of the graph G ( wG ) as ∑ni=1∑nj=1dist(i,j) .
Now, Yuta has n nodes, and he wants to choose no more than m pairs of nodes (i,j)(i≠j) and then link edges between each pair. In this way, he can get an undirected graph G with n nodes and no more than m edges.
Yuta wants to know the minimal value of wG .
It is too difficult for Rikka. Can you help her?
In the sample, Yuta can choose (1,2),(1,4),(2,4),(2,3),(3,4) .
Input
The first line contains a number
t(1≤t≤10)
, the number of the testcases.
For each testcase, the first line contains two numbers n,m(1≤n≤106,1≤m≤1012) .
For each testcase, the first line contains two numbers n,m(1≤n≤106,1≤m≤1012) .
Output
For each testcase, print a single line with a single number -- the answer.
Sample Input
1 4 5
Sample Output
14
考虑直接以一个点为中心练成一个放射状的图
多出来的边再把发散出来的点两两连线
维护下每种情况的贡献即可
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<cassert>
#include<iostream>
#include<algorithm>
using namespace std;
int a[100001];
int main()
{
int T;
scanf("%d",&T);
while(T>0)
{
T--;
long long n,m;
scanf("%I64d%I64d",&n,&m);
if(m>=n*(n-1LL)/2LL)
{
printf("%I64d\n",n*(n-1LL));
continue;
}
long long ans=(n-1LL)*n*n;
long long i;
if(m<=n-1LL)
{
long long d=0;
for(i=1;i<=m;i++)
{
ans-=2LL*((n-1LL)+d*(n-2LL));
d++;
}
}
else
{
long long d=0;
for(i=1;i<=n-1LL;i++)
{
ans-=2LL*((n-1LL)+d*(n-2LL));
d++;
}
m-=(n-1LL);
ans-=2LL*m;
}
printf("%I64d\n",ans);
}
return 0;
}