纯代码,无分析
其他差分题:
语文成绩
反思:
差分数组的本质:每一项
a
i
a_i
ai是一步“变化量”,表示
s
i
s_i
si相对于
s
i
−
1
s_{i-1}
si−1的增量,这样就可以用两端一增一减表示中间的整体增大,和微积分有异曲同工之妙的感觉
时间复杂度O(n+m)
#include<iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
int p[N],A[N],B[N],C[N];
int subPass[N];//差分数组本体
int n,m;
ll sum;
int 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];
//计数给pass[N]
memset(subPass,0,sizeof(int)*(m+1));
for (int i = 1; i < m; i++)
{
int l=p[i];
int r=p[i+1];
if(l<r)
{
subPass[l]+=1;
subPass[r]-=1;
}
else
{
subPass[r]+=1;
subPass[l]-=1;
}
}
sum=0;
int pass=subPass[0];//其实就是初始0,此处pass作差分数组对应的前缀和的载体,因为只需要使用一次,不需要用数组
for (int i = 1; i < n; i++)
{
pass+=subPass[i];
if(pass!=0)
{
ll cost1=(ll)pass*A[i];
ll cost2=(ll)pass*B[i]+C[i];
sum += cost1<cost2 ? cost1:cost2;
}
}
cout<<sum;
}