• 【CF1485F】Copy or Prefix Sum 题解


    原题链接

    题意简介

    根据给定的数组 (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
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    洛谷P1196银河英雄传说
    NOIP2011普及组第三题瑞士轮(洛谷P1309)
    Dijkstra算法
    10.13做题——洛谷1449后缀表达式
    NOI题库(1.12.T3)甲流病人初筛
    10.12做题——NOI题库(1.13.T30)1的个数
    NOIP考试必备——随机数
    10.10做题——USACO1.2/洛谷1207回文平方数(Dual Palindromes)
    10.9做题——洛谷P1927防护伞
    10.9做题——USACO1.2/洛谷1206回文平方数(Palindromic Squares)
  • 原文地址:https://www.cnblogs.com/Qing-LKY/p/CF1485F-solution.html
Copyright © 2020-2023  润新知