Little relyt871 has a magical machine. In each operation, his machine can do one of the following operations to the input array bb:
b′={b1,b2,…,b|b|,b1,b2,…,b|b|}.b′={b1,b2,…,b|b|,b1,b2,…,b|b|}.
b′={b|b|,b|b−1|,…,b1,b1,b2,…,b|b|}.b′={b|b|,b|b−1|,…,b1,b1,b2,…,b|b|}.
Initially, he has an array aa of length nn. Then, he wants to operate the machine exactly mm times using the array on his hand while maximizing the sum of all prefix sums of the final array. Since he has a somewhat finite brain, when he adds some integers, he only cares about the sum modulo 10000000071000000007. Formally, suppose after all mm operations he has array bb of length n′n′, he wants to maximize the following value:
(∑i=1n′∑j=1ibj)(mod1000000007).(∑i=1n′∑j=1ibj)(mod1000000007).
Please note that you should maximize the value after taking the modulo: the array with answer 10000000071000000007 before taking the modulo is considered less than the array with answer 11.
Input
The first line contains two integers nn and mm (1≤n,m≤1051≤n,m≤105).
The second line contains nn integers a1, a2,..., ana1, a2,..., an (1≤ai≤1091≤ai≤109) separated by spaces.
Output
Print a single integer in one line, denoting the answer.
Examples
input
2 1 1 2
output
15
input
5 10 26463 39326 86411 75307 85926
output
806275469
题意: 有一个长度为n的数组,还有m次操作,每次操作可以选择将数组copy一份拼接到原数组后面作为新数组,或者将数组copy一份拼接到翻转后的数组后面作为新数组。问经过恰好m次操作后,最终数组的前缀和数组的和在模1e9+7下的最大值。
分析: 模拟一下发现当进行一次翻转后之后得到的数组都完全相同,于是可以根据这个性质枚举第几次翻转,然后统计答案。再进一步分析可以发现无论第几次翻转最终答案都不变,这是因为把两个第一次翻转位置不同的最终数组摆到一起,剔除相同位置的相同数值,剩下的一定是2*t个位置,且其中t个位置升序,t个位置逆序,这样两数组最终贡献上的差值就抵消了,所以最终答案就两种情况,一种是不进行翻转操作,一种是最后一次才进行翻转。
具体代码如下:
- #include
- #define int long long
- using namespace std;
-
- const int mod = 1e9+7;
- int a[100005], b[100005], p2[100005], n, m;
-
- int f(int len, int type){//len段时的贡献,1代表全1,2代表全2
- int res = 0;
- if(type == 1)
- for(int i = 1; i <= n; i++)
- res = ((res+a[i]*((((1+len)*len/2)%mod)%mod*n%mod-len*(i-1)%mod)%mod)+mod)%mod;
- else
- for(int i = 1; i <= n; i++)
- res = ((res+b[i]*((((1+len)*len/2)%mod)%mod*n%mod-len*(i-1)%mod)%mod)+mod)%mod;
-
- return res;
- }
-
- signed main(){
- scanf("%lld%lld", &n, &m);
- p2[0] = 1;
- for(int i = 1; i <= m; i++)
- p2[i] = p2[i-1]*2%mod;
- for(int i = 1; i <= n; i++)
- scanf("%lld", &a[i]);
- reverse(a+1, a+n+1);
- memcpy(b, a, sizeof a);
- reverse(a+1, a+n+1);
- int ans1 = f(p2[m], 1);
- int ans2 = ((f(p2[m], 2)-f(p2[m-1], 2)+f(p2[m-1], 1))%mod+mod)%mod;
- printf("%lld\n", max(ans1, ans2));
-
- return 0;
- }