码迷,mamicode.com
首页 > 其他好文 > 详细

【CF1485F】Copy or Prefix Sum 题解

时间:2021-02-17 14:08:47      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:等价   构造   while   链接   直接   情况下   target   for   std   

原题链接

题意简介

根据给定的数组 \(B\),现要求你构造出数组 \(A\),使数组 \(A\) 的每个位置 i,都满足下面的条件:

\(A_i=B_i\)\(\sum^i_{j=1}A_j=B_i\)

求问数组 A 的构造方案有多少种?

思路分析

首先,从通过人数上看,这题比 E 题容易。

显然,这是一道计数的题目。

从题意我们可以看出,对于每个 i 位置上的数,只有下列两种可能:

  1. \(A_i=B_i\)

  2. \(A_i=B_i-sum\) (sum 为 \(\sum^{i-1}_{j=1}A_j\)

假如每个位置都有上述两条世界线可以走的话,最终构造出的数组会有 \(2^n\) 种。

但事情并没有这么简单,我们发现,存在某些情况下,上述两个条件恰好等价,即 \(sum=0\)。此时,这一状态便没有两条世界线了。

于是,我们想到,维护到每个位置时各个 sum 对应的世界线的数量,然后在统计 i 的影响时,加入把上面的特殊情况取出来特殊考虑就行了。

不难看出,i 的影响如下:

  1. 将 sum 变为 \(B_i\)

  2. 将 sum 加上 \(B_i\)

对于第二种情况,可以用全局变量方便地维护。

利用 hash 表维护 sum 对应的世界线数量即可。

代码库

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,a,b) for(int i=a;i>=b;i--)
const ll N=2e5+5,mod=1e9+7,M=300007,STEP=233;
int T,n; ll B[N],delta; 
ll hsh[M],cnt[M];
inline int find(ll x){
    int p=(x-x/M*M+M)%M;
    while(cnt[p]!=0&&hsh[p]!=x) p=(p+STEP)%M;
    return p;
}
inline void add(ll x,ll c){
    int p=find(x);
    hsh[p]=x; cnt[p]=(cnt[p]+c)%mod;
}
inline ll count(ll x){
    int p=find(x);
    return cnt[p];
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        rep(i,1,n) scanf("%lld",B+i);
        memset(cnt,0,sizeof(cnt));
        memset(hsh,0,sizeof(hsh));
        delta=0; add(0,1); // sum 一开始只有 0 一种
        ll ans=1;
        rep(i,1,n){
            int tmp=(ans-count(-delta)+mod)%mod; // tmp 表示 i-1 的所有方案中 sum 不为 0 的情形 对应两种世界线都可以走的情况
            add(-delta,tmp); // 因为之后 bi 会加到 delta 上 所以此处对应 sum 直接变成 bi 的情况。
            ans=(ans+tmp)%mod; 
            delta+=B[i]; // 本来的情况直接加上 bi 的情形
        }
        printf("%lld\n",ans);
    }
    return 0;
}

【CF1485F】Copy or Prefix Sum 题解

标签:等价   构造   while   链接   直接   情况下   target   for   std   

原文地址:https://www.cnblogs.com/Qing-LKY/p/CF1485F-solution.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!