[bzoj]4547小奇的集合

[bzoj]4547小奇的集合


先排序找最大的两个数x1,x2

然后发现 两个数都大于0时可以矩阵优化算出和 其他情况特判一下

  • 代码
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
ll mod=10000007;
int n,k;
ll s[100010],res;

struct Matrix {
    ll a[10][10];
    int n;

    ll* operator [] (int x) {
        return a[x];    
    }
    Matrix operator* (Matrix b) {
        Matrix c;
        c.n=n;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        for(int k=1;k<=n;k++)
			c[i][k]=(c[i][k]+a[i][j]*b[j][k])%mod;    
        return c;
    }
    Matrix operator^ (int e) {
        Matrix res,tmp=*this;
        res.init(n);
        while(e) {
            if(e&1) res=res*tmp;
            tmp=tmp*tmp;
            e>>=1;    
        }
        return res;
    }
    void init(int k) {
		n=k;for(int i=1;i<=n;i++) a[i][i]=1;    
    }
    
    Matrix() {
		memset(a,0,sizeof(a));    
	}
}g;

int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;++i)
		scanf("%lld",&s[i]);
	sort(s+1,s+n+1);
	if(s[n]<0&&s[n-1]<0){
		res=k*(s[n]+s[n-1])%mod;
		for(int i=1;i<=n;i++)res=(res+s[i]+mod)%mod;
		printf("%lld\n",res);
		return 0;
	}
	if(s[n-1]<0&&s[n]>0){
		int p=(-s[n-1]-1)/(s[n])+1;
		p=min(p,k);
		res+=1ll*(p)*s[n-1]+(1ll*p*(p-1)/2)%mod*s[n]%mod;
		k-=p;
		s[n-1]=p*s[n]+s[n-1];
	}
	g.n=3,g[2][1]=1,g[1][1]=2,g[1][3]=-1,g[3][2]=1;
	g=g^k;
	res+=(1ll*g[1][1]*(s[n]+s[n-1])%mod+1ll*g[1][2]*s[n-1]%mod+mod)%mod;
	res%=mod;
	for(int i=1;i<=n-2;i++){
		res+=s[i];res%=mod;
		if(res<0)res+=mod;
	}
	printf("%lld\n",res);
}

猜你喜欢

转载自blog.csdn.net/qq_35923186/article/details/82807584