首页 > 其他分享 >Living-Dream 系列笔记 第14期

Living-Dream 系列笔记 第14期

时间:2024-03-09 12:37:15浏览次数:16  
标签:Living 14 int sum 差分 100031 long 数组 Dream

本期主要讲解差分技巧。

知识点

我们令原数组为 \(a_i\),则当且仅当 \(d_i=a_i-a_{i-1}\) 时,我们称 \(d_i\) 是 \(a_i\) 的差分数组。

特别的,\(d_1=0\),\(d_{n+1}=-n\)。

差分数组 \(d_i\) 有以下三个性质:

  • \(d_i\) 的前缀和数组为 \(a_i\)。

  • 将 \(a_{L \sim R}\) 这个区间统一加上 \(val\),等价于 \(d_L \gets d_L+val\) 且 \(d_{R+1} \gets d_{R+1}-val\)。

  • \(\sum^{n}_{i=1} d_i = 0\)。

例题

T1

板子题,放下代码供以后复习用。

#include<bits/stdc++.h>
using namespace std;

int n,p,ans=1e9+31;
int a[5000031],d[5000031];

int main(){
	cin>>n>>p;
	for(int i=1;i<=n;i++) cin>>a[i],d[i]=a[i]-a[i-1];
	while(p--){
		int x,y,z; cin>>x>>y>>z;
		d[x]+=z,d[y+1]-=z;
	}
	for(int i=1;i<=n;i++) a[i]=a[i-1]+d[i];
	for(int i=1;i<=n;i++) ans=min(ans,a[i]);
	cout<<ans; 
	return 0;
}

T2

有意思的结论题。

根据差分数组的性质二,我们知道 将 \(a_{L \sim R}\) 这个区间统一减少 \(1\),等价于 \(d_L \gets d_L-1\) 且 \(d_{R+1} \gets d_{R+1}+1\)。

而根据性质三,我们又知道 \(\sum^{n}_{i=1} d_i = 0\),这就说明差分数组中的正负数可以互相抵消。

因此,我们可以求出差分数组,再一正一负地进行对原数组的区间操作,这样每次操作后差分数组的正数和会 \(-1\),而负数和会 \(+1\)。

若我们令差分数组的正数和为 \(S_1\),那么要让原数组变为全 \(0\)(也就是差分数组变为全 \(0\)),显然需要 \(S_1\) 次操作。

所以,我们仅需求出 \(S_1\) 即为答案。

#include<bits/stdc++.h>
using namespace std;

long long n,a[100031],d[100031],sum;

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i],d[i]=a[i]-a[i-1];
		if(d[i]>0) sum+=d[i];
	}
	cout<<sum; 
	return 0;
}

三倍经验:P5019P1969P3078

T3

对于一段铁路,我们仅能买票或者买卡,因此若第 \(i\) 段铁路经过的次数为 \(x\),则对于这一段铁路的最小花费为:

\[\min(a_i \times x,b_i \times x + c_i) \]

观察上式,\(a_i,b_i,c_i\) 我们都是已知的,因此影响铁路最小花费的因素只有其经过的次数。问题转变为了如何统计每一段铁路被经过的次数。

很容易想到对于 \(m\) 次旅程依次枚举累加,但会 \(\color{navy}{\texttt{TLE}}\)。

于是我们想到对于第 \(i\) 次旅程都是将 \(\min(P_i,P_{i+1}) \sim \max(P_i,P_{i+1})\) 之间的铁路经过次数累加 \(1\),因此考虑采用差分优化,将区间操作转为单点操作即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;

int n,m,ans=0;
int p[100031];
int a[100031],b[100031],c[100031];
int cnt[100031];

signed main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++) cin>>p[i];
	for(int i=1;i<n;i++) cin>>a[i]>>b[i]>>c[i];
	for(int i=1;i<m;i++)
		cnt[min(p[i],p[i+1])]++,cnt[max(p[i],p[i+1])]--;
	for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
	for(int i=1;i<n;i++) ans+=min(a[i]*cnt[i],b[i]*cnt[i]+c[i]);
	cout<<ans;
	return 0;
}

标签:Living,14,int,sum,差分,100031,long,数组,Dream
From: https://www.cnblogs.com/XOF-0-0/p/18062512

相关文章

  • Living-Dream 系列笔记 第15期
    模拟赛爆炸祭。T1把所有连通块依次求出,若某个连通块的数量已经出现过,则说明它与以前的连通块属于同一星系,直接将星系大小加上连通块大小并取\(\max\);否则将星系数量\(+1\)。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;intn,m;intans=-1e9,num,......
  • Living-Dream 系列笔记 第11期
    本期主要讲解与上期相同内容(雾。例题T1在整个矩阵外加一圈\(0\),使得包围圈外的\(0\)形成一整个连通块。求出这个连通块并标记为\(1\),然后输出即可。#include<bits/stdc++.h>usingnamespacestd;intn;intdx[]={-1,0,1,0},dy[]={0,1,0,-1};inta[31][31],g[31][31];......
  • Living-Dream 系列笔记 第12期
    本期主要讲解一维前缀和技巧。知识点我们令\(a_i\)表示原数组的第\(i\)个元素,则\(sum_i\)表示\(a_i\)前\(i\)个元素之和,即:\[sum_i=\sum^{i}_{j=1}a_j\]我们知道,\(a\)数组前\(i\)个元素的和\(=\)前\(i-1\)个元素的和\(+a_i\)。于是便可得到\(sum\)数组的......
  • Living-Dream 系列笔记 第13期
    本期主要讲解二维前缀和。知识点我们令\(a_{i,j}\)表示原数组,则\(sum_{i,j}\)为\(a\)的二维前缀和数组。根据容斥原理,得到递推式:\[sum_{i,j}=sum_{i-1,j}+sum_{i,j-1}-sum_{i-1,j-1}+a_{i,j}\]二维前缀和适用于求静态矩阵的子矩阵元素和。若我需要求一个左上角坐标为......
  • Living-Dream 系列笔记 第10期
    本期主要讲解进阶\(\text{DFS}\)。知识点\(\text{DFS}\)求解连通块问题:定义:若一个点集中的所有点都能互达,且与集合外的点无法互达,则称此点集为一个连通块。考查方式:求连通块数量/大小/周长。例题T1在\(\text{DFS}\)函数中传入参数\(x\)和\(str\),分别表示......
  • Living-Dream 系列笔记 第8期
    本期主要讲解的与上期相同。例题T1上课的时候调这个题感觉要吐了\(qwq\)。。。首先读入\(n\)行字符串,可以采取忽略中间无关单词的方式来直接读取\(X\)和\(Y\)。将所有名字存入\(a\)数组,对\(a\)数组按字典序排序后就可以开始\(\text{DFS}\)了,这里建议使用next_pr......
  • Living-Dream 系列笔记 第9期
    模拟赛掉大分(悲T1板子,不讲。T2首先很明显这题是个去重全排列。和模板的区别就是加了一个\(sum\)参数记录目前已经放了几个苹果。当\(x=n+1\)时若\(sum=m\),则更新答案。同时加入一个剪枝:若在搜索过程中\(sum>m\),则直接return结束搜索。#include<bits/stdc++.h>usi......
  • Living-Dream 系列笔记 第6期
    模拟赛。寄。T1对于每次询问,二分查找数组中对应值的原下标即可,因此需要用结构体存储原始数据和原始下标。这当然是比较麻烦的做法。另一种做法则是开一个map替代桶来存储数组中每个元素的下标,对于每个询问输出即可。另外值得注意的是,本题默认询问之间相互独立。时间复杂度......
  • Living-Dream 系列笔记 第7期
    本期主要讲解深度优先搜索\(\text{DFS}\)。知识点种类:全排列。可以想象为填格子。去重全排列,即组合。时间复杂度均为\(O(n!)\)。\(\text{DFS}\)题的特征:求方案总数/最值。数据范围极小(一般\(n\le20\))。无法直接暴力枚举(因为循环嵌套层数不确定)。......
  • Living-Dream 系列笔记 第4期
    本期主要讲解二分答案。知识点使用场景:最小值最大化,或最大值最小化。在限制条件下找最值。与二分查找的区别:L、R均为答案,而非下标。输出:最大化输出L,反之输出R。例题T1二分\(M\)的值,边界为\(L=-1,R=\max{\{a_i\}}\)。每次枚举到一个\(mid\)就对于每个......