1. 程式人生 > >loj516 「LibreOJ β Round #2」DP 一般看規律

loj516 「LibreOJ β Round #2」DP 一般看規律

clear pac ret stdio.h eoj 技術 sort logs targe

傳送門:https://loj.ac/problem/516

【題解】

那段代碼求的是相同的數中間隔最小的值。

離散後用set維護每個值出現次數,每次操作相當於合並兩個set,這步可以啟發式合並。

加元素的時候直接找前驅和後繼即可。

學了新姿勢:set中insert有返回的,可以訪問.first來調用新插入元素的iterator

技術分享
# include <set>
# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include 
<algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int N = 1e5 + 10, M = 3e5 + 10; const int mod = 1e9+7, inf = 2147483647; int n, m, a[N]; struct quest { int x, y; }q[N]; vector<int> ps;
set<int> s[M]; set<int>::iterator it, it2; int ans[M], Ans = inf, id[M]; inline int getid(int x) { return lower_bound(ps.begin(), ps.end(), x) - ps.begin() + 1; } int main() { cin >> n >> m; for (int i=1; i<=n; ++i) { scanf("%d", a+i); ps.push_back(a[i]); }
for (int i=1; i<=m; ++i) { scanf("%d%d", &q[i].x, &q[i].y); ps.push_back(q[i].x); ps.push_back(q[i].y); } sort(ps.begin(), ps.end()); ps.erase(unique(ps.begin(), ps.end()), ps.end()); for (int i=1; i<=n; ++i) a[i] = getid(a[i]); for (int i=1; i<=m; ++i) q[i].x = getid(q[i].x), q[i].y = getid(q[i].y); for (int i=1; i<=n; ++i) s[a[i]].insert(i); for (int i=1; i<=ps.size(); ++i) { ans[i] = inf; id[i] = i; if(s[i].size() < 2) continue; for (it = s[i].begin(), it2 = ++s[i].begin(); it2 != s[i].end(); ++it, ++it2) ans[i] = min(ans[i], *it2 - *it); Ans = min(Ans, ans[i]); } for (int i=1, X, Y, x, tans; i<=m; ++i) { X = q[i].x, Y = q[i].y; if(!s[id[X]].size()) { printf("%d\n", Ans); continue; } if(!s[id[Y]].size()) { swap(id[X], id[Y]); printf("%d\n", Ans); continue; } tans = min(ans[id[X]], ans[id[Y]]); if(s[id[X]].size() > s[id[Y]].size()) swap(id[X], id[Y]); for (it = s[id[X]].begin(); it != s[id[X]].end(); ++it) { x = *it; it2 = s[id[Y]].insert(x).first; ++it2; if(it2 != s[id[Y]].end()) tans = min(tans, *it2 - x); --it2; if(it2 != s[id[Y]].begin()) --it2, tans = min(tans, x - *it2); } s[id[X]].clear(); ans[id[Y]] = tans; ans[id[X]] = inf; Ans = min(Ans, tans); printf("%d\n", Ans); } return 0; }
View Code

loj516 「LibreOJ β Round #2」DP 一般看規律