2018 Summer ACM cattle off network multi-school training camp (first) F: Sum of Maximum

The meaning of problems: a given number N a [], and now form a new array b with a [], 1 <= b [i] <= a [i]. Q. maximum value of all the programs and.

Ideas: first order. Then segmentation statistical contribution, assuming a [i-1] <a [i], then [a [i-1] + 1, a [i]] contribution was left all programs * legitimate right of the program, that is legitimate is the maximum value within this range.

Suppose max = x, then the contribution of the right side is x * (x ^ (n-i + 1) - (x-1) * (n-i + 1)); all x add up to find a prefix and, = x ^ (n-i + 2) + (x-1) ^ (n-i + 1) + ... ^ (n-i + 1); rightmost portion may be determined using Lagrangian.

All would be finished. But my board seems a bit slow.

(After all, I added an extra log, change it tomorrow. Today there are a few questions to make up.

(But in reality it is in preparation for the board.

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=200010;
const int Mod=1e9+7;
const int mod=1e9+7;
int a[maxn],sum[maxn],ans;
ll f[maxn],fac[maxn],inv[maxn];
ll P(ll a,ll b)
{
    ll ans=1;
    while(b) {
        if(b&1) ans=ans*a%mod;
        b>>=1; a=a*a%mod;
    }
    if(ans<0) ans+=mod;
    return ans;
}
void init(int tot)
{
    fac[0]=1;
    for(int i=1;i<=tot;i++)
        fac[i]=fac[i-1]*i%mod;
    inv[tot]=P(fac[tot],mod-2);
    inv[0]=1; //求阶乘逆元
    for(int i=tot-1;i>=1;i--)
        inv[i]=inv[i+1]*(i+1)%mod;
}
ll Lagrange(ll n,ll k)
{
    rep(i,1,k+1) f[i]=(f[i-1]+P(i,k-1))%mod;
    if(n<=k+1) return f[n];
    int tot=k+1; init(tot);
    ll ans=0,now=1;
    for(int i=1;i<=tot;i++) now=now*(n-i)%mod;
    for(int i=1;i<=tot;i++) {
        ll inv1=P(n-i,mod-2);
        ll inv2=inv[i-1]*inv[tot-i]%mod;
        if((tot-i)&1) inv2=mod-inv2;
        ll temp=now*inv1%mod;
        temp=temp*f[i]%mod*inv2%mod;
        ans+=temp;
        if(ans>=mod) ans-=mod;
    }
    return ans;
}
int solve(int x,int k)
{
    if(!x) return 0;
    return P(x,k+1)-Lagrange(x-1,k+1);
}
int main()
{
    int N;
    while(~scanf("%d",&N)){
        rep(i,1,N) scanf("%d",&a[i]);
        sort(a+1,a+N+1); ans=0; sum[0]=1;
        rep(i,1,N) sum[i]=1LL*sum[i-1]*a[i]%Mod;
        rep(i,1,N) {
            if(a[i]==a[i-1]) continue;
            int res=(solve(a[i],N-i+1)-solve(a[i-1],N-i+1)+Mod)%Mod;
            (ans+=1LL*sum[i-1]*res%Mod)%=Mod;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/hua-dong/p/11455218.html