<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      *題解:P12700 [KOI 2022 Round 2] 停車場

      原題鏈接

      解析

      \(f_i\) 表示取完了編號為 \(a_i\) 的車,最后取出的是第 \(i\) 個格子上的車所需的最少操作次數。枚舉上一層終點 \(j\) 進行轉移:

      \[f_i=\min(f_j + \operatorname{dis}(pre_i,j) + \operatorname{ACW}(pre_i,i),f_j + \operatorname{dis}(nxt_i,j) + \operatorname{CW}(nxt_i,i)) \]

      其中 \(\operatorname{dis}(i,j)\) 表示從第 \(i\) 個格子走到第 \(j\) 個格子所需的最少步數,\(\operatorname{CW}(i,j)\)\(\operatorname{ACW}(i,j)\) 分別表示從 \(i\) 順、逆時針走到 \(j\) 的步數,\(pre_i,nxt_i\) 分別表示在 \(i\) 之前逆時針和 \(i\) 之后順時針第一個編號為 \(a_i\) 的位置。

      這樣直接轉移復雜度是 \(O(n)\) 的,考慮優化,以 \(f_j + \operatorname{dis}(pre_i,j) + \operatorname{ACW}(pre_i,i)\) 為例,先把和 \(j\) 有關的項提取出來:

      \[f_j + \operatorname{dis}(pre_i,j) \]

      拆開 \(\operatorname{dis}\) 變為:

      \[f_j + \operatorname{min}(\lvert pre_i-j\rvert,n-\lvert pre_i-j\rvert) \]

      欽定 \(pre_i > j\) 拆絕對值:

      \[f_j + \operatorname{min}(pre_i-j,n-pre_i+j) \]

      只考慮跟 \(j\) 有關的項,求出 \(f_j - j\)\(f_j + j\) 的前綴最小值再加上二分就可以做到 \(O(\log n)\) 轉移。\(pre_i \le j\) 的情況同理,詳見代碼。

      代碼

      時間復雜度 \(O(n\log n)\)。當然你也可以用雙指針替代二分從而省下轉移過程中的 \(\log\)

      #include <bits/stdc++.h>
      #define ls(x) ((x) << 1)
      #define rs(x) (((x) << 1) | 1)
      #define mid ((l + r) >> 1)
      using namespace std;
      typedef long long ll;
      typedef pair<int,int> pii;
      const int N = 1e6 + 5,M = 100 + 5,mod = 998244353;
      int a[N],pre[N],nxt[N];
      ll f[N],premn1[N],premn2[N],sufmn1[N],sufmn2[N];
      vector<int> pos[N];
      int n;
      int CW(int a,int b){
      	if(b >= a) return b - a;
      	return n - (a - b);
      }
      int ACW(int a,int b){
      	if(a >= b) return a - b;
      	return n - (b - a);
      }
      int main(){
      	ios::sync_with_stdio(false);
      	cin.tie(0);
      	memset(f,127,sizeof(f));
      	memset(premn1,127,sizeof(premn1));
      	memset(premn2,127,sizeof(premn2));
      	memset(sufmn1,127,sizeof(sufmn1));
      	memset(sufmn2,127,sizeof(sufmn2));
      	cin>>n;
      	vector<int> v;
      	for(int i=1;i<=n;i++){
      		cin>>a[i];
      		v.push_back(a[i]);
      	}
      	sort(v.begin(),v.end());
      	v.erase(unique(v.begin(),v.end()),v.end());
      	for(int i=1;i<=n;i++){
      		a[i] = lower_bound(v.begin(),v.end(),a[i]) - v.begin() + 1;
      		pos[a[i]].push_back(i);
      	}
      	for(int i=1;i<=v.size();i++){
      		for(int j=0;j<pos[i].size();j++){
      			if(j)
      				pre[pos[i][j]] = pos[i][j - 1];
      			if(j + 1 < pos[i].size())
      				nxt[pos[i][j]] = pos[i][j + 1];
      		}
      		pre[pos[i][0]] = pos[i].back();
      		nxt[pos[i].back()] = pos[i][0];
      	}
      	pos[0].push_back(0);
      	f[0] = 0;
      	premn1[0] = sufmn1[0] = 1;
      	premn2[0] = sufmn2[0] = -1;
      	ll res = 9e18;
      	for(int i=1;i<=v.size();i++){
      		for(int j : pos[i]){
      			auto it = lower_bound(pos[i - 1].begin(),pos[i - 1].end(),pre[j]);//pre[j] < k
      			int k = pos[i - 1].back();
      			//f[k] + min(k - pre[j],n - k + pre[j])
      			if(it != pos[i - 1].end()){
      				k = *it;
      				f[j] = min(f[j],min(sufmn1[k] - pre[j],n + sufmn2[k] + pre[j]) + ACW(pre[j],j));
      			}
      			if(k > pre[j]) k = pre[k];
      			if(k < pre[j]){
      				//pre[j] > k
      				//f[k] + min(pre[j] - k,n - pre[j] + k)
      				f[j] = min(f[j],min(premn2[k] + pre[j],n + premn1[k] - pre[j]) + ACW(pre[j],j));
      			}
      			it = lower_bound(pos[i - 1].begin(),pos[i - 1].end(),nxt[j]);
      			k = pos[i - 1].back();
      			if(it != pos[i - 1].end()){
      				k = *it; 
      				f[j] = min(f[j],min(sufmn1[k] - nxt[j],n + sufmn2[k] + nxt[j]) + CW(nxt[j],j));
      			}
      			if(k > nxt[j]) k = pre[k];
      			if(k < nxt[j]){
      				f[j] = min(f[j],min(premn2[k] + nxt[j],n + premn1[k] - nxt[j]) + CW(nxt[j],j));
      			}
      			premn1[j] = f[j] + j,premn2[j] = f[j] - j;
      			if(pre[j] < j){
      				premn1[j] = min(premn1[j],premn1[pre[j]]);
      				premn2[j] = min(premn2[j],premn2[pre[j]]);
      			}
      			if(i == v.size()){
      				res = min(res,f[j]);
      			}
      		}
      		for(int j=pos[i].size() - 1;j>=0;j--){
      			int t = pos[i][j];
      			sufmn1[t] = f[t] + t,sufmn2[t] = f[t] - t;
      			if(j < pos[i].size() - 1){
      				sufmn1[t] = min(sufmn1[t],sufmn1[nxt[t]]);
      				sufmn2[t] = min(sufmn2[t],sufmn2[nxt[t]]);
      			}
      		}
      	}
      	cout<<res;
      	return 0;
      }
      
      posted @ 2025-10-22 12:03  yuyce  閱讀(0)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 女人腿张开让男人桶爽| 亚洲成在人线在线播放无码| 久久久av男人的天堂| 狠狠色丁香婷婷久久综合五月| 91精品国产色综合久久| 日韩av第一页在线播放| 熟女精品色一区二区三区| 亚洲一二三区精品美妇| 国产福利社区一区二区| 老师破女学生处特级毛ooo片| 亚洲国产成人久久精品app| 粉嫩av一区二区三区蜜臀| 狂野欧美性猛交免费视频| 色综合夜夜嗨亚洲一二区| 国产福利在线观看免费第一福利| 99久久精品费精品国产一区二| 精品熟女少妇av免费久久| 免费福利视频一区二区三区高清| 最近中文字幕免费手机版| 欧美最新精品videossexohd| 91久久天天躁狠狠躁夜夜| 亚洲嫩模喷白浆在线观看| 苍井空毛片精品久久久| 日本内射精品一区二区视频| 热久在线免费观看视频| 无码精品一区二区免费AV| 亚洲色欲久久久久综合网| 亚洲天码中文字幕第一页| 国产成人亚洲欧美二区综合| 久9视频这里只有精品| 欧美私人情侣网站| 日本久久香蕉一本一道| 久久一区二区三区黄色片| 不卡一区二区国产精品| 怡红院一区二区三区在线| 日本边添边摸边做边爱喷水| 日韩av裸体在线播放| 色综合久久精品中文字幕| 福利一区二区在线观看| 亚洲AV国产福利精品在现观看| 无码免费大香伊蕉在人线国产|