这是个简单明了的差分。
普通模拟做这种题一定会爆掉的。洛谷数据非常真实,一定会做一个和上限一样大的数据。不要企图靠运气蒙混过关。
我们只需要用一个序列表示第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; }
就这么愉快的结束了。