CF1009E [Intercity Travelling]

这道题先考虑一种暴力n方做法

\(f_i\)表示到\(i\)点所有情况的困难度之和(\(f_0=0\)),\(pre_i=\sum_{j=1}^{i} a_j\)

考虑从点\(j\)中途不经过休息站到达\(i\),可以得到\[f_i=pre_i+\ \sum_{j=1}^{i-1} f_j+2^{j-1}pre_{i-j}\]

(要乘\(2^{j-1}\)是因为到第\(j\)个点有那么多方案)

这个很容易就能优化到\(O(n)\)

\(g_i=\sum_{j=1}^{i} f_j,h_i=pre_i+\sum_{j=1}^{i-1} 2^{j-1}pre_{i-j}=\sum_{j=1}^{i}2^{i-j}a_j=2h_{i-1}+a_i\)

所以\[f_i=g_{i-1}+h_i\]

直接\(O(n)\)救星了,也不要多开数组

#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double

using namespace std;
const int mod=998244353,N=1000000+10;
il LL rd()
{
    re LL x=0,w=1;re char ch;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
LL n,a[N],an,ss,bb; //乱定变量名(逃

int main()
{
  n=rd();
  for(int i=1;i<=n;i++) a[i]=rd();
  for(int i=1;i<=n;i++)
    {
      bb=((bb<<1)%mod+a[i])%mod;
      an=(ss+bb)%mod;
      ss=(ss+an)%mod;
    }
  printf("%lld\n",an);
  return 0;
}

转载于:https://www.cnblogs.com/smyjr/p/9483696.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值