JZOJ5872-小A的任务
题目描述
输入格式
第一行,为任务数n
第一行,n个数,第i个数为任务i的价值Si
输出格式
第一行,为最大优美程度
第二行,为选择的任务数
样例一
input
3
1 2 3
output
624
3
限制与约定
对于10%的数据,保证n<=5
对于40%的数据,保证N<=10
对于70%的数据,保证N<=500
对于100%的数据,保证N<=10^7,1<=si<=n
题解:
这题首先必须要知道一个结论,不知道就只能用n3的方法来做,只有70分(真亏是T1....)
这个结论很简单,就是上面两个算分的式子,第一个大于等于第二个,且取等条件是Si=Sj=Sk。
怎样证明呢,比较简单的一种就是柯西不等式(停课选手表示知道也无奈)。
首先柯西不等式(一般式)的结论是:
对于两组数a,b(组内数的个数相同)有
至于为什么,之前上课时就说过可以用向量证明二维柯西不等式,具体的自己去看吧。。
因此由柯西不等式可得:

所以除非所有元素相等,全部都是要选的。
接下来把第一个式子转成两部分计算相加即可,下面是co的另一份题解(懒)

#include<bits/stdc++.h> #define ll long long using namespace std; const int mod=1e9+7,N=1e7+7; int n; ll a[N],ans=0,inv=0; ll ksm(ll y,int b){ ll x=1; while(b){ if(b&1) x=x*y%mod; y=y*y%mod; b>>=1; } return x; } int main() { int i; scanf("%d",&n); ll t=0,tt=0,p=3*n*n%mod; bool b=1; for(i=1;i<=n;i++){ scanf("%lld",&a[i]); ans=(ans+p*a[i]%mod)%mod;inv=(inv+ksm(a[i],mod-2))%mod; if(i>1&&tt!=a[i])b=0; tt=a[i]; a[i]=a[i]*a[i]%mod; } t=n*6;for(i=1;i<=n;i++) ans=(ans+t*inv%mod*a[i]%mod)%mod; if(b)printf("%lld\n0",ans); else printf("%lld\n%d",ans,n); }


浙公网安备 33010602011771号