1. 程式人生 > >1960 範德蒙矩陣(數學貪心)

1960 範德蒙矩陣(數學貪心)

1960 範德蒙矩陣

  LYK最近在研究範德蒙矩陣與矩陣乘法,一個範德蒙矩陣的形式如下:
它想通過構造一個含有1~nm的n*m的矩陣G,使得G*V得到的n*n的矩陣T中所有位置上的元素之和最大。其中n,m<=100000,ai<=2*10^9。 你只需輸出這個值對1e9+7取模後的結果。    思路:    然後推廣一下就是每一個G列向量乘以每一個V行向量的和,然後直接貪心就行了。

 

#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const ll mod = 1e9 + 7;
const int maxn = 100010;
ll num[maxn];

ll inv(ll t, ll p = mod)
{//求t關於p的逆元,注意:t要小於p,最好傳參前先把t%p一下 
    return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p;
}
ll pow(ll x, ll n)
{
    ll ans 
= 1; for (; n;n>>=1, x=x*x%mod) if (n & 1)ans = ans*x%mod; return ans; } int main() { ll n, m; scanf("%lld%lld", &n, &m); for (int i = 1; i <= m; ++i) scanf("%lld", &num[i]); sort(num + 1, num + m+1); ll ans = 0; for (int i = 1; i <= m; ++i) { ll a0
= ((i - 1)*n + 1)%mod, an = i*n%mod; ll A = (a0 + an) % mod*n%mod*inv(2)%mod, X; num[i] %= mod; if (num[i] == 0)X = 1; else if (num[i] == 1)X = n; else { X = (pow(num[i], n) - 1) % mod*inv(num[i] - 1) % mod; } ans = (ans + X*A%mod) % mod; } printf("%lld\n", ans); }