2022 China Collegiate Programming Contest (CCPC) Guilin Site - C. Array Concatenation

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯西可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值