HDU 6533 (贪心&递推)

显然是对边排序,从小到大选,把图画一下,对每层进行递推,维护前一个层的 s u m sum sum,每次 s u m × n sum\times n sum×n,然后再加上当前层的边权即可。

// Problem: B - Build Tree
// Contest: Virtual Judge - 2019CCPC湖南全国邀请赛(广东省赛、江苏省赛)重现赛 [Cloned]
// URL: https://vjudge.net/contest/457173#problem/B
// Memory Limit: 65 MB
// Time Limit: 1500 ms
// Date: 2021-09-08 16:31:43
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define IOS ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\n",a[n]); 
}
ll k,m,n,p,sum,ans,id,now;
ll a[N];
int main(){
	while(~scanf("%lld%lld%lld%lld",&k,&m,&n,&p)){
	now=n,id=sum=ans=0;
	rep(i,1,k) scanf("%lld",&a[i]);sort(a+1,a+k+1);
	rep(i,2,m){
		sum=sum*n%p;
		rep(j,1,now) sum=(sum+a[++id])%p;
		ans=(ans+sum)%p;
		now*=n;
	}printf("%lld\n",ans);
	}
	return 0;
}