这是个简单明了的差分。

普通模拟做这种题一定会爆掉的。洛谷数据非常真实,一定会做一个和上限一样大的数据。不要企图靠运气蒙混过关。

我们只需要用一个序列表示第i条道路经过了多少次就好了。我们用一个差分序列来计算这个序列,差分序列的第i个表示他比第i-1个大多少。然后计算他的前缀和就好了。(有点模糊

我们来一个序列证明一下:

1 3 5 7 6 4 2 0 这个是正常序列。

1 2 2 2 -1 -2 -2 -2 这就是差分序列,差分序列的第i个表示他比第i-1个大多少。

1 3 5 7 6 4 2 0 如果要求原序列的第i个,就把差分序列的前i个数加起来。

差分简介完毕。

所以说我们只要在开头处+1,然后在结尾处的下一个-1就好了。

以上面的计算方法,中间的数都会多一个。然后我们就快乐的计算下性价比就好啦。

简单的代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
struct hehe
{
	long long a,b,c; //题目中的A,B,C
}sz[100005];
long long n,m,cf[100005],cs[100005],sr[100005],shu;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
    	cin>>sr[i];
    	if(i!=1)
    	{
    		cf[min(sr[i],sr[i-1])]+=1;
    		cf[max(sr[i],sr[i-1])]-=1;//差分,这里写的没有错,确实是在终点的下一个减一。具体原因请大家自己思考
		}
	}
	for(int i=1;i<=n-1;i++)
	{
		cs[i]=cs[i-1]+cf[i];//求出每条路走过几次。
		cin>>sz[i].a>>sz[i].b>>sz[i].c;
	}
	for(int i=1;i<=n-1;i++)
	{
		shu+=min(cs[i]*sz[i].a,sz[i].c+cs[i]*sz[i].b);//计算性价比。
	}
	cout<<shu<<endl;
    return 0;
}

就这么愉快的结束了。

02-14 03:48