牛客网暑期ACM多校训练营(第一场)F

题解:这里我们可以得知最后结果与a[i]摆放的位置顺序无关。

那么假设我大于等于x的a有n个,小于x的有m个并且他们的积为y,那么我们得到x的方案数(不算y)再乘以x就是

我们接着可以把上面式子转化为x*(x^n-(x-1)^n),然后因为a很大我们不可能枚举每点的x

所以我们可以将大于等于某个数个数一样的合起来一起算那么假设区间长度是a~b那么我们可以大于他们的个数都是n个那么我们可以得到

b*(b^n-(b-1)^n)

(b-1)*((b-1)^n-(b-2)^n)

(b-2)*((b-2)^n-(b-3)^n)

.....

a*(a^n-(a-1)^n)

将上面式子简后就是b^(n+1)-(b-1)^n-(b-2)^n-(b-3)^n-.....-a^n-a*(a-1)^n然后我们中间那些数就需要自然数幂和了,可以看下这篇博客:https://blog.csdn.net/acdreamers/article/details/38929067

 

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define mes(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define dec(i,a,b) for(int i = b; i >= a; i--)
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define lowbit(x) x&(-x)
typedef double db;
typedef long long int ll;
typedef pair pii;
typedef unsigned long long ull;
const ll inf = 0x3f3f3f3f;
const int mx = 1e3+5;
const int mod = 1e9+7;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
int a[mx],b[mx];
ll c[mx][mx];
ll inv[mx];
ll B[mx];
ll modexp(ll x,ll n){
    ll ans = 1;
    while(n){
        if(n&1) ans = ans*x%mod;
        x = x*x%mod;
        n /= 2;
    }
    return ans;
}
void init(){
    for(int i = 0; i < mx; i++)
        for(int j = 0; j <= i; j++)
            if(j==0||j==i)
                c[i][j] = 1;
            else
                c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod;
    inv[1] = 1;
    for(int i = 2; i < mx; i++){
        inv[i] = (mod-mod/i)*inv[mod%i]%mod;
    }
    B[0] = 1;
    for(int i = 1; i < mx-1; i++){
        ll ans = 0;
        for(int j = 0; j < i; j++){
            ans = ans+c[i+1][j]*B[j]%mod;
            ans %= mod;
        }
        B[i] =  -ans*inv[i+1]%mod;
        B[i] = (B[i]+mod)%mod;
    }
}
ll getsum(ll x,int n){
    ll ans = 0;
    ll f = 1;
    for(int i = 1; i <= n+1; i++){
        f = f*(x+1)%mod;
        ans = ans+c[n+1][i]*B[n+1-i]%mod*f%mod;
        ans %= mod;
    }
    ans = ans*inv[n+1]%mod;
    return ans;
}
int main(){
    int ans = 0;
    init();
    int t,q,ca = 1;
    while(~scanf("%d",&n)){
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        a[0] = 1;
        b[0] = 0;
        ll ans = 1;
        int m = 0;
        for(int i = 1; i <= n; i++)
            if(a[m]==a[i])
                b[m]++;
            else{
                a[++m] = a[i];
                b[m] = 1;
            }
        ll pre = 1;
        int num = b[0];
        for(int i = 1; i <= m; i++){
            int x = n-num;
            ll sum1 = modexp(a[i],x+1)-(a[i-1]+1)*modexp(a[i-1],x)%mod;
            ll sum2 = (getsum(a[i]-1,x)-getsum(a[i-1],x))%mod;
            sum1 = (sum1-sum2+mod)%mod;
            ans = (ans+pre*sum1%mod+mod)%mod;
            num += b[i];
            pre = pre*modexp(a[i],b[i])%mod;
        }
        ans = (ans+mod)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

 

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