Minimal Power of Prime【数学(找规律)】

Minimal Power of Prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 5331 Accepted Submission(s): 328

Problem Description
You are given a positive integer n > 1. Consider all the different prime divisors of n. Each of them is included in the expansion n into prime factors in some degree. Required to find among the indicators of these powers is minimal.

Input
The first line of the input file is given a positive integer T ≤ 50000, number of positive integers n in the file. In the next T line sets these numbers themselves. It is guaranteed that each of them does not exceed 10^18.

Output
For each positive integer n from an input file output in a separate line a minimum degree of occurrence of a prime in the decomposition of n into simple factors.

Sample Input
5
2
12
108
36
65536

Sample Output
1
1
2
2
16

题目大意:
首先知道两点之间的权值例如点 a a a和点 b b b之间的权值等于 a & b a\&b a&b,有 T T T组测试数据,对于每组测试数据,输入一个数 n n n,代表有 n n n个点,此时需建立一棵树,使得树的权值最小。需先输出最小权值为多少,再输出从点 2 2 2到点 n n n每个点连接的点是哪个。

解题思路:
由于需要输出最小权值的树,就需使得边的权值尽可能小,由于点 a a a和点 b b b之间的权值等于 a & b a\&b a&b,我们可以发现对于任意一个点,我们都可以找到另一个点与之取与后使得边的权值为 0 0 0,例如当 n n n等于 6 6 6时,对于点 2 2 2,其二进制第一个 0 0 0出现在第一位,所以与点 ( 1 < < 0 ) (1<<0) (1<<0)取与后权值为 0 0 0,对于点 3 3 3,由于 n = = 6 n==6 n==6其二进制为 3 3 3位,对 3 3 3的二进制补零后找出其第一次出现的 0 0 0的位置,在第 3 3 3位,将其点 ( 1 < < 2 ) (1<<2) (1<<2)相连,其边权值也就变为了 0 0 0,以此类推,最后即可得到最小权值树,且可得到最小的字典树序列。
ps.当 n = = ( 1 < < k ) − 1 n==(1<<k)-1 n==(1<<k)1时,此时第 n n n个点找不到第一个 0 0 0,即找不到一个点与其相连使得边权值为 0 0 0,此时只能将其与点 1 1 1相连。因此我们可以发现,最后的树的最小权值要么为 0 0 0、要么为 1 1 1

代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue ,greater >q;
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
int arr[200100];
int num[30];
int main() 
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    #endif
    //freopen("out.txt", "w", stdout);
    //ios::sync_with_stdio(0),cin.tie(0);
    int T;
    scanf("%d",&T);
    for(int i=0,j=1;i<20;i++,j++) {
    	num[j]=(1<

你可能感兴趣的:(数学)