HDU 5922 Minimum’s Revenge(思維題)——2016CCPC東北地區大學生程序設計競賽 - 重現賽

此文章可以使用目錄功能喲↑(點擊上方[+])

 HDU 5922 Minimum’s Revenge

Accept: 0    Submit: 0
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

 Problem Description

There is a graph of n vertices which are indexed from 1 to n. For any pair of different vertices, the weight of the edge between them is the least common multiple of their indexes.

Mr. Frog is wondering about the total weight of the minimum spanning tree. Can you help him?

 Input

The first line contains only one integer T (T≤100), which indicates the number of test cases.

For each test case, the first line contains only one integer n (2≤n≤10^9), indicating the number of vertices.

 Output

For each test case, output one line "Case #x:y",where x is the case number (starting from 1) and y is the total weight of the minimum spanning tree.

 Sample Input

2
2
3

 Sample Output

Case #1: 2
Case #2: 5
Hint
In the second sample, the graph contains 3 edges which are (1, 2, 2), (1, 3, 3) and (2, 3, 6).
Thus the answer is 5.

 Problem Idea

解題思路:

【題意】
現有一個n個結點的一個圖

這n個結點的指數分別爲1~n

現在規定一條邊的權值爲該邊兩個端點的指數的最小公倍數

問這n個點構成的最小生成樹的總權值

【類型】
最小生成樹+最小公倍數=思維
【分析】
考慮到n個結點的最小生成樹有n-1條邊

這意味着我們要挑選出n-1個最小公倍數

再考慮到兩個正整數a和b,它們的最小公倍數c必定滿足c≥max(a,b)

即LCM(a,b)≥max(a,b)

而我們知道最小生成樹會包含1~n這n個結點

那麼生成樹的總權值ans必定滿足


當且僅當取到等號時,生成樹爲最小生成樹

當然,這種生成樹也是我們輕而易舉能夠構造出來的,如下:


【時間複雜度&&優化】
O(1)

題目鏈接→HDU 5922 Minimum’s Revenge

 Source Code

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-9
#define LL long long
#define PI acos(-1.0)
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 100005;
const int M = 100005;
const int inf = 1000000007;
const int mod = 1000000007;
int main()
{
    int t,p=1;
    __int64 n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%I64d",&n);
        printf("Case #%d: %I64d\n",p++,(n+2)*(n-1)/2);
    }
    return 0;
}
菜鳥成長記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章