題解 P3406 【海底高鐵】
阿新 • • 發佈:2020-08-29
實際發表時間:2020-04-22
https://www.luogu.com.cn/problem/P3406
思路:差分
我們寫一個差分陣列\(cnt_i\),表示\(vis_i-vis_{i-1}\)
\(vis\)就是第\(i\)段鐵路的訪問次數,\(vis_0=0\)。
那麼\(vis_n\)
\(=vis_1-vis_1+vis_2-vis_2+\cdots+vis_{n-1}-vis_{n-1}+vis_n\)
\(=(vis_1-vis_0)+(vis_2-vis_1)+\cdots+(vis_n-vis_{n-1})\)
\(=cnt_1+cnt_2+\cdots+cnt_n\)
\(=\sum\limits_{i=1}^{n}cnt_i\)
那怎麼對差分陣列進行操作呢?
觀察一下:
一個差分陣列和原陣列
0------0------0------0------0
0------0------0------0------0
城市2~4(經過2~3)
0------1------0------(-1)------0
0------1------1------ 0 ------0
城市4~1(經過3~1)
1------1------0------(-2)------0
1------2------2------ 0 ------0
城市1~5(經過1~4)
2------1------0------(-2)------(-1)
2------3------3------ 1 ------ 0
不難發現,若是從城市\(n\)
然後每次輸入\(a_i,b_i,c_i\)時判斷\(vis_i \times a_i\)和\(vis_i \times b_i+c_i\)的大小即可,誰小答案就加誰
程式碼
#include<bits/stdc++.h> using namespace std; int n,m,cnt[100005],now,last,sum; long long ans,vis[100005];//記得開longlong struct node { long long a,b,c;//我喜歡寫結構體,用a[i],b[i],c[i]也行 }s[100005]; long long mymin(long long x,long long y){return x<y?x:y;}//longlong的min int main() { scanf("%d%d%d",&n,&m,&last); for(int i=1;i<m;i++) { scanf("%d",&now); cnt[min(now,last)]++,cnt[max(now,last)]--;//差分操作 last=now; } for(int i=1;i<n;i++)vis[i]=sum+=cnt[i];//計算vis[i] for(int i=1;i<n;i++) { scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].c); ans+=mymin(vis[i]*s[i].a,vis[i]*s[i].b+s[i].c);//比較 } printf("%lld",ans); return 0; }
最後——
記得開long long!