题目描述:
You need to construct a full n-ary tree(n叉树) with m layers.All the edges in this tree have a weight.But this weight cannot be chosen arbitrarily you can only choose from set S,the size of S is k,each element in the set can only be used once.Node 0 is the root of tree.
We use d(i) for the distance from root to node i.Our goal is to minimize the following expression:
min∑i=0Nd(i)
Please find the minimum value of this expression and output it.Because it may be a big number,you should output the answer modul p.
输入:
The input file contains 2 lines.
The first line contains 4 integers,these respectively is k,m,n,p。(2 ≤ k ≤200000,2 ≤ p≤ 1015)
The second line contains k integers,represent the set S,the elements in the set guarantee less than or equal to 1015.
We guarantee that k is greater than or equal to the number of edges.
输出:
The output file contains an integer.represent the answer.
样例输入:
5 2 3 10
1 2 3 4 5
样例输出:
6
题目大意是,给出n叉树,并给出层数,要求在以下的数字集合中选出数字,组成满n叉树,使得每一个结点到根节点的距离之和最大
根据贪心策略,使总距离最大,那么应该将较小的边放在尽可能靠前的位置
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
long long a[300000];
long long s[300000];
int main()
{
long long k,n,m,p;
while(~scanf("%lld%lld%lld%lld",&k,&m,&n,&p))
{
int i,j;
memset(a,0,sizeof(a));
memset(s,0,sizeof(s));
for(i=0;i<k;i++)
{
scanf("%lld",&a[i]);
}
std::sort(a,a+k);
int ceng=n;
int count=0;
for(i=2;i<=m;i++)
{
s[i]=(s[i-1]*n)%p;
for(j=0;j<ceng;j++)
{
s[i]=(s[i]+a[count++])%p;
}
ceng=ceng*n;
}
long long sum=0;
for(i=2;i<=m;i++)
{
sum=(sum+s[i])%p;
}
printf("%lld\n",sum);
}
return 0;
}