题目链接

点我跳转

题目大意

给定一个长度为 \(N\) 的序列 \(bi\)

问有多少个长度为 \(N\) 的序列 \(a\) 使得

  • \(b[i] = a[i]\)

  • \(b[i] = ∑a[j] , j∈[1,i]\)

解题思路

定义 $dp[i][j] $ 表示前 \(i\) 项的前缀和为 \(j\) 的序列 \(a\) 的个数,其中 \(dp[0][0] = 1\)

( 因为前缀和很大,所以需要用 \(map\) 来操作 )

那么:

  1. 当 \(b[i] = a[i]\) 时 , \(dp[i][j] = dp[i - 1][j - b[i]]\)

  2. 当 \(b[i] = ∑a[j] , j∈[1,i]\) 时 , \(dp[i][b[i]] = ∑dp[i - 1][j],j∈[-inf,inf]\)

对于第一种转移相当于把整个数组的值向右平移 \(b[i]\)

对于第二种转移需要注意当 \(sum[i-1] = 0\) 时,\(b[i]\) 既等于 \(a[i]\) 又等于 \(∑a[j] , j∈[1,i]\)

相当于多转移了一次 \(dp[i - 1][0]\) ,所以需要减去 \(dp[i - 1][0]\)

最后的答案 \(ans = ∑dp[n][j],j∈[-inf,inf]\) ,复杂度为 \(N^2logN\) ( \(log\) 的复杂度源于 \(map\) )

考虑优化:

定义 \(sum[i]\) 表示长度为 \(i\) 且满足题目条件的序列 \(a\) 的个数

对于第一种转移,只是把数值向右平移,并不会导致答案的个数增加,所以 \(sum[i] = sum[i - 1]\)

对于第二种转移,\(dp[i][b[i]] += sum[i - 1]\) , 同时减去 \(dp[i - 1][0]\) ,相当于 \(sum[i] += sum[i - 1] , sum[i] -= dp[i - 1][0]\)

于是我们可以定义 \(py\) 表示平移的长度,起初 \(py = 0\),每计算完 \(sum[i]\) 后 , 令 \(py += b[i]\)

那么 \(dp[i - 1][j]\) 则可以用 \(dp[j - py]\) 表示

而 \(dp[i][j]\) 则可以用 \(dp[j - py - b[i]]\) 表示

于是可得 \(sum[i] += sum[i - 1] - dp[0 - py]\) , \(dp[b[i] - py - b[i]] += sum[i - ] - dp[0 - py]\)

最后的答案 \(ans = sum[n]\) , 复杂度为 \(NlogN\)

AC_Code

#include<bits/stdc++.h>

#define int long long

using namespace std;

const int N = 3e5 + 10 , mod = 1e9 + 7;

map<int , int>dp;

int b[N];

signed main()
{
int T = 1; cin >> T; while(T --)
{
dp.clear(); int n , sum = 1 , py = 0; cin >> n; for(int i = 1 ; i <= n ; i ++) cin >> b[i]; dp[0] = 1; for(int i = 1 ; i <= n ; i ++)
{
int add = (sum - dp[0 - py] + mod) % mod; sum = (sum + add) % mod , py += b[i]; dp[b[i] - py] = (dp[b[i] - py] + add) % mod;
} cout << sum << '\n';
} return 0;
}

Codeforces 1485F Copy or Prefix Sum的更多相关文章

  1. 4.4 CUDA prefix sum一步一步优化

    1. Prefix Sum 前缀求和由一个二元操作符和一个输入向量组成,虽然名字叫求和,但操作符不一定是加法.先解释一下,以加法为例: 第一行是输入,第二行是对应的输出.可以看到,Output[1] ...

  2. 牛客多校第十场-D- Rikka with Prefix Sum

    链接:https://www.nowcoder.com/acm/contest/148/D来源:牛客网 Prefix Sum is a useful trick in data structure p ...

  3. 牛客网暑期ACM多校训练营(第十场)D Rikka with Prefix Sum (数学)

    Rikka with Prefix Sum 题意: 给出一个数组a,一开始全为0,现在有三种操作: 1.  1 L R W,让区间[L,R]里面的数全都加上W: 2.  2     将a数组变为其前缀 ...

  4. Codeforces 703D Mishka and Interesting sum 离线+树状数组

    链接 Codeforces 703D Mishka and Interesting sum 题意 求区间内数字出现次数为偶数的数的异或和 思路 区间内直接异或的话得到的是出现次数为奇数的异或和,要得到 ...

  5. Rikka with Prefix Sum(组合数学)

    Rikka with Prefix Sum 题目描述 Prefix Sum is a useful trick in data structure problems. For example, giv ...

  6. Educational Codeforces Round 53 E. Segment Sum(数位DP)

    Educational Codeforces Round 53 E. Segment Sum 题意: 问[L,R]区间内有多少个数满足:其由不超过k种数字构成. 思路: 数位DP裸题,也比较好想.由于 ...

  7. Rikka with Prefix Sum

    Rikka with Prefix Sum 题目 https://www.nowcoder.com/acm/contest/148/D 题目有三个操作 l到r都添加一个数 取一次前缀和 查询区间和 这 ...

  8. Codeforces Round #556 (Div. 2) - C. Prefix Sum Primes(思维)

    Problem  Codeforces Round #556 (Div. 2) - D. Three Religions Time Limit: 1000 mSec Problem Descripti ...

  9. Educational Codeforces Round 1 A. Tricky Sum 暴力

    A. Tricky Sum Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/598/problem ...

随机推荐

  1. MySQL常见优化

    MySQL常见优化 1.操作符优化 1.1<> 操作符(不等于) 1.2LIKE优化 1.3in,not in,exists与not exists 1.3.1in和exists 2.whe ...

  2. java架构《Socket网络编程基础篇》

    本章主要介绍Socket的基本概念,传统的同步阻塞式I/O编程,伪异步IO实现,学习NIO的同步非阻塞编程和NIO2.0(AIO)异步非阻塞编程. 目前为止,Java共支持3种网络编程模型:BIO.N ...

  3. string知识

    因为历史原因以及为了与C语言兼容,字符串字面值与标准库string类型不是同一种类型.这一点很容易引起混乱,编程时一定要注意区分字符串字面值和string数据类型的使用,这很重要. 额~~~C字符串是 ...

  4. Cisco动态路由(rip)

    接Cisco静态路由,讨论一下Cisco动态路由. 实验环境布置 命令布置动态路由 Router0: Router>enable Router#configure terminal Router ...

  5. mysql-mysqli_fetch_all(错误)

    mysql-mysqli_fetch_all(错误) 问题:使用mysql-mysqli_fetch_all获取返回的数组时失败/报错 原因及解决方法: mysqli_fetch_all函数只存在于m ...

  6. zabbix添加持续告警

  7. Java复习整理 Day02

    1 package demo01; 2 3 import java.util.Scanner; 4 5 public class ScannerDemo01 { 6 public static voi ...

  8. Flutter--Dart基础语法(四)异步

    前言 Flutter 是 Google 开源的 UI 工具包,帮助开发者通过一套代码库高效构建多平台精美应用,Flutter 开源.免费,拥有宽松的开源协议,支持移动.Web.桌面和嵌入式平台. Fl ...

  9. HashMap 和 Hashtable两者的区别以和解释

    HashMap 和 Hashtable 是 Java 开发程序员必须要掌握的,也是在各种 Java 面试场合中必须会问到的. 但你对这两者的区别了解有多少呢? 现在,栈长我给大家总结一下,或许有你不明 ...

  10. sentinel流量控制和熔断降级执行流程之源码分析

    前言: sentinel是阿里针对服务流量控制.熔断降级的框架,如何使用官方都有很详细的文档,下载它的源码包 里面对各大主流框都做了适配按理,本系列文章目的 主要通过源码分析sentinel流量控制和 ...