日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ3387栅栏行动

發布時間:2023/11/29 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ3387栅栏行动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.



首先,很容易想到Dp。設f[i][0]表示第i個柵欄走左邊的最短路,f[i][1]表示第i個柵欄走右邊的最短路。

所以,我們要找一個剛好在第i個柵欄的左右邊界下面的柵欄。如圖所示:


則有:

f[i][0] = min(f[k][0] + |Left[i] - Left[k]| , f[k][1] + |Left[i] - Right[k]| )

f[i][1] = min(f[j][0] + |Right[i] - Left[j]| , f[j][1] + |Right[i] - Right[j]| )


那么,該怎樣求k和j呢?

很容易想到開一個數組,從小到大覆蓋。但這樣的時間復雜度是O(n^2)的。用線段樹區間修改,單點查詢就可以了。

附上程序:

#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <string> #include <cstdlib> #include <bitset> #include <fstream> #include <queue> #include <stack> #include <map> #include <set> #include <ctime> #include <deque> #include <vector> #include <complex> #include <utility> using namespace std; typedef long long LL; #define INF 0x3fffffff #define Maxn 100010int num[Maxn<<1]; int f[Maxn][2];int n,m;int a[Maxn],b[Maxn];#define L(u) u<<1 #define R(u) u<<1|1struct Tnode{int l,r;bool isset;int set; }; Tnode tr[Maxn<<3];void build(int u,int l,int r) {tr[u].l = l; tr[u].r = r;tr[u].isset = true; tr[u].set = 0;if(l<r){int mid = (l+r)>>1;build(L(u),l,mid);build(R(u),mid+1,r);} }void pushdown(int u) {if(tr[u].isset){tr[L(u)].isset = tr[R(u)].isset = true;tr[L(u)].set = tr[R(u)].set = tr[u].set;tr[u].isset = tr[u].set = 0;} }void update(int u,int l,int r,int val) {if(l<=tr[u].l && tr[u].r<=r){tr[u].isset = true;tr[u].set = val;return;}pushdown(u);int mid = (tr[u].l+tr[u].r)>>1;if(mid>=l) update(L(u),l,r,val);if(mid<r) update(R(u),l,r,val); }int query(int u,int p) {if(tr[u].l==tr[u].r)return tr[u].set;pushdown(u);int mid = (tr[u].l+tr[u].r)>>1;if(p<=mid) return query(L(u),p);else return query(R(u),p); }int main() { scanf("%d%d",&n,&m);build(1,1,Maxn<<1);a[n+1] = b[n+1] = m;for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);int k1,k2;for(int i=1;i<=n+1;i++){k1 = query(1,a[i]+100005);k2 = query(1,b[i]+100005);f[i][0] = min(f[k1][0]+abs(a[i]-a[k1]),f[k1][1]+abs(a[i]-b[k1]));f[i][1] = min(f[k2][0]+abs(b[i]-a[k2]),f[k2][1]+abs(b[i]-b[k2]));if(a[i]+1<b[i])update(1,a[i]+100005+1,b[i]+100005-1,i);}printf("%d\n",f[n+1][0]);return 0; }

轉載于:https://www.cnblogs.com/ouqingliang/p/9245248.html

總結

以上是生活随笔為你收集整理的BZOJ3387栅栏行动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。