首页 > 编程语言 >浅谈C++简单前缀和实现

浅谈C++简单前缀和实现

时间:2024-01-19 22:11:07浏览次数:28  
标签:浅谈 int cin long C++ using tie 前缀

浅谈前缀和 2023.9.28

\(tips:\) 文章持续更新中,欢迎关注
\(upd:\)文章从洛谷博客迁移至博客园(\(2024.1.19\))

洛谷B3612 【深进1.例1】求区间和

题目大E:

有一个内部元素个数为\(n\)的数组\(a\),现在有m次询问,求a[l]到a[r]之间所有元素的和

朴素的做法:

#include <iostream>
using namespace std;
using ll = long long;
const int N = 1e5 + 5;//数据范围1e5
int a[N];//数组a
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); //取消同步流 加快i/o速度
    int n; cin >> n;//读入n
    for(int i = 1; i <= n; i++) cin >> a[i];
    int m; cin >> m; //读入m
    while(m--)//循环m次
    {
        int ans = 0; 
        int l, r; cin >> l >> r;
        for(int i = l; i <= r; i++)//i从l到r
            ans += a[i];//累加a[i]
        cout << ans << '\n';//输出ans
    }

    return 0;
}

这样其实也是能AC的

但是,4.35秒的时间显然不够让人满意

简单一算复杂度\(O(m(r-l))\)
数据稍微大一点就会TLE,可以去ETOJ[oj.eriktse.com]里的模板前缀和提交相同的代码看结果
但是有没有一种方法,能够代替这种不尽人意的结果呢?

前缀和做法

我们可以新建一个数组\(p\), p[i]表示从a[1]到a[i]a数组内所有元素的和
可以得出计算公式:\(p[i] = p[i - 1] + a[i]\)
其实其中也蕴含了递推的思想

#include <iostream>
using namespace std;
using ll = long long;
const int N = 1e5;
int a[N], p[N]; //创建a数组和前缀和数组
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n; cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i]; //读入数组a
    for(int i = 1; i <= n; i++) p[i] = p[i - 1] + a[i]; //计算前缀和
    int m; cin >> m; //读入m
    while(m--)//循环m次
    {
        int l, r; cin >> l >> r;
        cout << p[r] - p[l - 1] << '\n';//从1到r减去从1到l-1,就是r~l区间的和
    }

    return 0;
}

是不是很优雅?
而同时这种代码也拥有较为优秀的时间复杂度:\(O(n)\)的计算时间,\(O(1)\)的询问复杂度

太优雅了

135ms和4s你选哪一个

总结

前缀和其实更多的是一种思想,运用前缀和思想解题才是最重要的

例题:P8772 [蓝桥杯 2022 省 A] 求和

本题其实也有朴素的做法

但是如果你使用朴素的做法,那么恭喜你荣获30分

题目大E:

根据我们小学二年级就学过的乘法分配律,我们可以得出:
\(S = a[1] * (a[2] + a[3] + ... + a[n - 1] + a[n] ) + a[2] * (a[3] + a[4] + ... + a[n]) + a[n - 1] * a[n]\)

而a[i]乘的那一个算式,就是对a[i + 1]到a[n]求和,通过前缀和可以直接求出,而不用像朴素的做法那样一个一个乘一个一个加

完整AC代码

#include <iostream>
using namespace std;
#define int long long
const int N = 2 * 1e5 + 5;
int a[N], p[N];
signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);//不解释了
    int n; cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) p[i] = p[i - 1] + a[i];//计算前缀和
    int ans = 0;
    for(int i = 1; i < n; i++)
        ans += a[i] * (p[n] - p[i]);//对a[i-1]到a[n]求和,用p[n]-p[i],最后累加
    cout << ans << '\n';//输出答案

    return 0;
}

END

好了,前缀和后面还会再讲一讲,目前就先到这里--2023/9/29 00:06

祝看到这篇文章的人rp++

END

标签:浅谈,int,cin,long,C++,using,tie,前缀
From: https://www.cnblogs.com/zhaoyihang/p/17975739

相关文章

  • C++-类和对象(1)
    引言:C++语言兼容C语言的基础上,更多的是面向对象进行编程,即相较于事务处理的流程,更侧重于处理过程中涉及到的类以及对象。今天向大家分享C++中的类与对象相关知识。1.类的定义:常使用class关键字定义一个类:由两部分构成,分别是成员属性和成员函数。classclassName//类名{//成员......
  • C++中对象作为函数参数进行传参
    在C++语言环境中,对象是类的一个实例。 有三种方式:1、直接使用对象作为函数参数,形参和实参是不同的对象,它们所占地址空间不同,因此形参的改变并不影响实参的值。2、传入指向对象的指针作为函数参数,所谓“传址调用”,就是在函数调用时使用实参对象的地址,形参和实参都指向同一个地......
  • 车载视频JT1078协议视频接入(C++)
    把之前做的JT1078协议车载视频接入进行文档整理如下:-----------------------------------------------------------------------------------------------一。背景;平台能够通过jt808协议接入车辆GPS定位信息的基础上,扩展车载视频JT1078协议的接入。实现车辆位置信息和视频信......
  • 【计算机算法设计与分析】罗密欧与朱丽叶的迷宫问题(C++_回溯法)
    文章目录题目描述测试样例算法原理算法实现参考资料题目描述罗密欧与朱丽叶的迷宫。罗密欧与朱丽叶身处一个mxn的迷宫中,如图所示。每一个方恪表示迷宫中的一个房间。这mxn个房间中有一些房间是封闭的。不允任何人进入。在迷宫中任何位置均可沿8个方向进入未封闭的房间。罗密......
  • C++ Qt开发:Charts与数据库组件联动
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍Charts组件与QSql数据库组件的常用方法及灵活运用。在之前的文章中详细介绍了关于QCharts绘图组件......
  • 图论——浅谈理论,DFS序和欧拉序
    图论——浅谈理论,DFS序、时间戳和欧拉序提示:本文在树论基础上。下文图例DFS序:124579836.欧拉序:124457997885236631.回加欧拉序:124257975852123631.下文举例均指此图。DFS序周所周知,DFS为深度优先遍历,其框架如:voiddfs(i......
  • C/C++ 实现动态资源文件释放
    当我们开发Windows应用程序时,通常会涉及到使用资源(Resource)的情况。资源可以包括图标、位图、字符串等,它们以二进制形式嵌入到可执行文件中。在某些情况下,我们可能需要从可执行文件中提取自定义资源并保存为独立的文件。在这篇博客文章中,我们将讨论如何使用C++和WinAPI实现这个目标......
  • C++ 邮件槽ShellCode跨进程传输
    在计算机安全领域,进程间通信(IPC)一直是一个备受关注的话题。在本文中,我们将探讨如何使用Windows邮件槽(Mailslot)实现ShellCode的跨进程传输。邮件槽提供了一种简单而有效的单向通信机制,使得任何进程都能够成为邮件槽服务器,并通过UDP通信向其他进程发送数据。邮件槽是Windows操作系统......
  • C++ 共享内存ShellCode跨进程传输
    在计算机安全领域,ShellCode是一段用于利用系统漏洞或执行特定任务的机器码。为了增加攻击的难度,研究人员经常探索新的传递ShellCode的方式。本文介绍了一种使用共享内存的方法,通过该方法,两个本地进程可以相互传递ShellCode,从而实现一种巧妙的本地传输手段。如果你问我为何在本地了......
  • #星计划# 浅谈OpenHarmony的NDK开发
    背景NativeAPI(NDK)入门NativeAPI是OpenHarmonySDK上提供的一组native开发接口与工具集合(也称为NDK),方便开发者使用C或者C++语言实现应用的关键功能。NativeAPI只覆盖了OHOS基础的一些底层能力,如libc,图形库,窗口系统,多媒体,压缩库等,并没有完全提供类似于JSAPI上的完整的OHOS平台......