[BZOJ]4547: Hdu5171 小奇的集合 矩阵乘法
2017-04-15 11:42
288 查看
Description
有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值。(数据保证这个值为非负数)
Input
第一行有两个整数n,k表示初始元素数量和操作数,第二行包含n个整数表示初始时可重集的元素。对于100%的数据,有 n<=10^5,k<=10^9,|ai|<=10^5
Output
输出一个整数,表示和的最大值。答案对10000007取模。一看就是矩阵乘法啦……注意一下一开始的最大有负数的情况以及众多细节就好了……
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define LL long long const LL mod=10000007; const LL inf=2147483647; LL n,a[100005],k; struct matrix{LL m[3][3],l,r;}u,ans,o; matrix cheng(matrix x,matrix y) { ans.l=y.l;ans.r=x.r; memset(ans.m,0,sizeof(ans.m)); for(LL i=0;i<=ans.l;i++) for(LL j=0;j<=ans.r;j++) for(LL k=0;k<=x.l;k++) { ans.m[i][j]+=x.m[k][j]*y.m[i][k]; ans.m[i][j]=(ans.m[i][j]+mod)%mod; } } void work(matrix b,LL k) { if(k==1) o=b; else { work(b,k/2); cheng(o,o);o=ans; if(k%2==1) { cheng(b,o); o=ans; } } } int main() { LL m1=-inf,m2=-inf,sum=0; scanf("%lld%lld",&n,&k); for(LL i=1;i<=n;i++) { scanf("%lld",&a[i]);a[i]%=mod; sum+=a[i];sum%=mod; } sort(a+1,a+1+n); m1=a ;m2=a[n-1]; if(m2<0) { while(1) { sum=sum+m2+m1; sum=(sum+mod)%mod; m2+=m1; k--; if(m2>=0) break; } } if(k==0) {printf("%lld",sum);return 0;} u.l=u.r=2; u.m[0][0]=0;u.m[0][1]=1;u.m[0][2]=0; u.m[1][0]=1;u.m[1][1]=1;u.m[1][2]=0; u.m[2][0]=1;u.m[2][1]=1;u.m[2][2]=1; matrix v; v.l=2;v.r=0; v.m[0][0]=m2;v.m[1][0]=m1;v.m[2][0]=sum; work(u,k); cheng(v,o); printf("%lld",ans.m[2][0]); }
相关文章推荐
- 【BZOJ4547】Hdu5171 小奇的集合 矩阵乘法
- bzoj 4547: Hdu5171 小奇的集合 (矩阵乘法+递推)
- 【BZOJ4547】【HDU5171】小奇的集合,暴力+矩阵乘法
- 【bzoj4547】【小奇的集合】【矩阵乘法】
- bzoj 4547: Hdu5171 小奇的集合
- bzoj 4547: Hdu5171 小奇的集合 矩阵乘法
- 【BZOJ 4547】【HDU 5157】小奇的集合
- [BZOJ4547]小奇的集合(矩乘)
- 4547: Hdu5171 小奇的集合
- 【bzoj4547】Hdu5171 小奇的集合 矩阵乘法
- bzoj 4547 小奇的集合
- 【BZOJ-4547】小奇的集合 矩阵乘法 + 递推
- 【bzoj 4547】【Hdu 5171】小奇的集合(找规律+矩阵快速幂)
- 【jozj5228】【GDOI2018模拟7.14】【小奇的集合】【矩阵乘法】
- 【BZOJ4547】小奇的集合
- BZOJ 2738: 矩阵乘法|分块|整体二分
- [BZOJ1009]HNOI2008 GT考试|KMP|递推|矩阵乘法
- BZOJ 2004|HNOI 2010 Day 1|公交线路|状态压缩动态规划|矩阵乘法
- bzoj4417 超级跳马 矩阵乘法
- [BZOJ 2326] HNOI 2011 数学作业 · 矩阵乘法