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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

题解 DTOJ #1438. 矮人排队(lineup)

發布時間:2025/7/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 题解 DTOJ #1438. 矮人排队(lineup) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

歡迎訪問 My Luogu Space。


【題目大意】

\(n\) 個身高為 \([1,\ n]\) 的且各不相同的人排成一個序列。

有兩種操作:

  • 讓位置 \(x,\ y\) 的人交換位置。
  • 給定一個范圍\([l,\ r]\),詢問身高在該范圍內的所有人是否排成了一個連續的序列。
  • 輸出操作二的詢問。


    【題解】

    線段樹

    操作一很簡單。

    對于操作二:

    我們發現身高在 \([l,\ r]\) 的人一共有 \(k=(r-l+1)\) 個。

    我們只需要找到身高在這個范圍內,且站在最左端和最右端的人的坐標。

    \((\)右坐標\(-\)左坐標 \(+1)\) 的值如果等于 \(k\),那么這 \(k\) 個人就剛好排成了一個連續的序列。

    如果大于就是這 \(k\) 個人當中被插入了一些其他人,不可能有小于的情況出現。

    因此我們需要支持查詢坐標的最大和最小值。

    建一棵以身高為下標的線段樹,值為身高對應的坐標,區間查詢坐標的最大和最小值。


    【代碼】

    // output format !! // long long !! #include <bits/stdc++.h> #define ls (x<<1) #define rs (x<<1|1) const int MAXN = 200000+10; using std::max; using std::min; using std::swap; struct TREE{int Max, Min;}t[MAXN*4];int n, m, h[MAXN], loc[MAXN], L, R;void build(int x, int l, int r){if(l == r) return t[x].Max = t[x].Min = loc[l], void();int mid = (l+r)>>1;build(ls, l, mid), build(rs, mid+1, r);t[x].Max = max(t[ls].Max, t[rs].Max);t[x].Min = min(t[ls].Min, t[rs].Min); } void query(int x, int l, int r, int ql, int qr){if(ql<=l && r<=qr){L = min(L, t[x].Min);R = max(R, t[x].Max);return;}int mid = (l+r)>>1;if(ql <= mid) query(ls, l, mid, ql, qr);if(qr > mid) query(rs, mid+1, r, ql, qr); } void modify(int x, int l, int r, int p, int v){if(l == r) return t[x].Max = t[x].Min = v, void();int mid = (l+r)>>1;if(p <= mid) modify(ls, l, mid, p, v);else modify(rs, mid+1, r, p, v);t[x].Max = max(t[ls].Max, t[rs].Max);t[x].Min = min(t[ls].Min, t[rs].Min); } int main(){scanf("%d%d", &n, &m);for(int i=1; i<=n; ++i) scanf("%d", h+i), loc[h[i]] = i;build(1, 1, n);while(m--){int op, x, y;scanf("%d%d%d", &op, &x, &y);if(op == 1){modify(1, 1, n, h[y], x);modify(1, 1, n, h[x], y);swap(h[x], h[y]), swap(loc[h[x]], loc[h[y]]);}else{L = 1e9, R = 0;query(1, 1, n, x, y);if(R-L+1 == y-x+1) puts("YES");else puts("NO");}}return 0; }

    轉載于:https://www.cnblogs.com/bosswnx/p/10988258.html

    總結

    以上是生活随笔為你收集整理的题解 DTOJ #1438. 矮人排队(lineup)的全部內容,希望文章能夠幫你解決所遇到的問題。

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