C. Array Concatenation
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
题目描述
Little relyt871 has a magical machine. In each operation, his machine can do one of the following operations to the input array b:
Generate a copy of b and concatenate it after b. More formally, the resulting array should be
b′={b1,b2,…,b|b|,b1,b2,…,b|b|}.
Generate a copy of b, reverse it, then concatenate it before b. More formally, the resulting array should be
b′={b|b|,b|b−1|,…,b1,b1,b2,…,b|b|}.
Initially, he has an array a of length n. Then, he wants to operate the machine exactly m 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 1000000007. Formally, suppose after all m operations he has array b of length n′, he wants to maximize the following value:
(∑i=1n′∑j=1ibj)(mod1000000007).
Please note that you should maximize the value after taking the modulo: the array with answer 1000000007 before taking the modulo is considered less than the array with answer 1.
输入描述
The first line contains two integers n and m (1≤n,m≤105).
The second line contains n integers a1, a2,…, an (1≤ai≤109) separated by spaces.
输出描述
Print a single integer in one line, denoting the answer.
题意
给定一个长度为 n 的数组我们可以做如下两种操作 m 次
i)复制这个数组放到原数组前面 长度2
ii)复制这个数组翻转后 放到原数组前面 长度2
求操作 m 次后得到数组的前缀和的和对 1e9+7 取模后的最大值
!!!:是取模后的最大值
即答案: 1e9+7<1
思路
不难发现 一个数组做了操作 2 后会变为一个回文数组 故之后的操作无论选择哪种得到的数组都是一样的 可以认为一种做操作 1 故可以枚举 最值只有 m 种不同的数组
而每一种前缀和的和的一步转移可以 O(1) 计算
而只做 操作1 x步可以推出权值公式 可以用快速幂快速计算
公式见代码
Code
#include<bits/stdc++.h>
using namespace std;
#define __T int csT;scanf("%d",&csT);while(csT--)
const int mod=1e9+7;
const int maxn=2e5+3;
int n,m;
long long a[100003],b[100003];
long long aq[100003],bq[100003],aqq[100003],bqq[100003];
long long ans;
long long qpow(long long a,long long x)
{
long long d=a,sum=1;
while(x>0)
{
if(x%2==1)sum=(sum*d)%mod;
d=(d*d)%mod;
x>>=1;
}
return sum;
}
void dfs(long long x,long long y,int f,long long q,long long len,int st)
{
if(st==m)
{
ans=max(ans,x);
return;
}
if(f==1)
{
long long t=m-st;
dfs((x*qpow(2,t)%mod+(q*len%mod*qpow(2,t-1)%mod*(qpow(2,t)-1+mod)%mod)%mod)%mod,0,1,0,0,m);
return;
}
dfs((x*2+q*len%mod)%mod,(y*2+q*len%mod)%mod,0,q*2%mod,len*2%mod,st+1);
dfs((x+y+q*len%mod)%mod,0,1,q*2%mod,len*2%mod,st+1);
}
inline void sol()
{
scanf("%d%d",&n,&m);
ans=0;
for(int i=1;i<=n;++i)
{
scanf("%lld",&a[i]);
b[n-i+1]=a[i];
}
for(int i=1;i<=n;++i)
{
aq[i]=aq[i-1]+a[i];
bq[i]=bq[i-1]+b[i];
}
for(int i=1;i<=n;++i)
{
aqq[i]=(aqq[i-1]+aq[i])%mod;
bqq[i]=(bqq[i-1]+bq[i])%mod;
}
dfs(aqq[n],bqq[n],0,aq[n],n,0);
printf("%lld\n",ans);
}
int main()
{
//__T
sol();
return 0;
}