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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

POJ - 2528 线段树+离散化

發(fā)布時(shí)間:2025/7/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ - 2528 线段树+离散化 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

其實(shí)很早就在白書上的常用技巧上 看到離散化的操作,但是之前一直沒(méi)遇到過(guò)需要離散化的題目(應(yīng)該是我太菜的緣故),所以一直也沒(méi)怎么重視,下面說(shuō)說(shuō)這道題目的考點(diǎn),也就是離散化

什么是離散化呢?請(qǐng)先自行百度理解了,一定先了解后再往下看。

?

那么該如何進(jìn)行操作呢?

?

舉個(gè)例子

假如 我們有5個(gè)數(shù)

?36? ?63431? 986357? 850159901? ? 2147483640?

很明顯? 它們的大小關(guān)系為? ?36 <?63431 <?986357??<?850159901?< 2147483640

?

但是,我們并不需要知道 36? ?63431? 986357? 850159901? ? 2147483640 它們實(shí)際的大小,只需要知道它們的相對(duì)大小就可以了

?

所以我們可以把? 36轉(zhuǎn)化為 1  63431轉(zhuǎn)化為2  986357轉(zhuǎn)化為3  850159901轉(zhuǎn)化為4  2147483640轉(zhuǎn)化為5

?

這樣我們得到了新的5個(gè)數(shù) 也就是 1 2 3 4 5

同時(shí),它們的相對(duì)大小還是一樣的? 1<2<3<4<5?

?

再用題目中的數(shù)據(jù)來(lái)舉個(gè)例子

1 5 1 4 2 6 8 10 3 4 7 10

?

我們得到了5個(gè)范圍,也就是1~4, 2~6, 8~10, 3~4, 7~10.

同樣的,我們并不需要知道它們的實(shí)際范圍,只需要知道它們的相對(duì)范圍就可以了

我們把它們每個(gè)點(diǎn)都整合起來(lái)? 所以就是? ?1 2 3 4 4 6 7 8 10 10

然后去掉重復(fù)的點(diǎn) 剩下 1 2 3 4 6 7 8 10

離散化得到新的范圍 1~4,? 2~5, 7~8, 3~4, 6~8

畫個(gè)圖會(huì)發(fā)現(xiàn),新的范圍 和 舊的范圍? 的? 相對(duì)范圍,其實(shí)是一樣的.

?

下面是這道題的思路:

  線段樹方面是常規(guī)操作,關(guān)鍵是這個(gè)離散化就有點(diǎn)特殊了

  首先我們測(cè)試下這個(gè)數(shù)據(jù)

  1
  3
  1 10
  1 4
  6?10

  會(huì)發(fā)現(xiàn)常規(guī)的離散化會(huì)覆蓋點(diǎn)5這個(gè)點(diǎn),而得到答案2,但是應(yīng)該是3才對(duì)

  這時(shí)候我們需要把每個(gè)點(diǎn)的右邊的數(shù)加入? 離散化的操作中來(lái)保證 連續(xù)性

  (但是這個(gè)題目的數(shù)據(jù)太弱,導(dǎo)致錯(cuò)誤的離散化也可以AC)

#include <algorithm> #include <iostream> #include<sstream> #include<iterator> #include<cstring> #include<string> #include<cstdio> #include<cctype> #include<vector> #include<deque> #include<map> #include<set>#define M 100005 #define inf 0x3f3f3f3f typedef long long ll; using namespace std;int T, n; int x, y, z; set<int>ans; vector<int>num;struct Data {int l, r, val, lazy; }tree[8*M];struct Data_x {int u, v; }loc_[M], loc[M];//loc_c是最初的數(shù)據(jù),loc是離散后的數(shù)據(jù)void built(int l, int r, int k) {tree[k].l = l, tree[k].r = r;tree[k].val = tree[k].lazy = 0;if (l == r)return;int mid = (l + r) / 2;built(l, mid, k << 1);built(mid + 1, r, (k << 1) | 1); }void down(int k) {tree[k << 1].val = tree[k << 1].lazy = tree[k].lazy;tree[(k << 1) | 1].val = tree[(k << 1) | 1].lazy = tree[k].lazy;tree[k].lazy = 0; }void change(int k) {if (tree[k].l >= x && tree[k].r <= y) {tree[k].val = z;tree[k].lazy = z;return;}if (tree[k].lazy)down(k);int mid = (tree[k].l + tree[k].r) / 2;if (x <= mid)change(k << 1);if (y > mid)change((k << 1) | 1);if (tree[k << 1].val == tree[(k << 1) | 1].val) tree[k].val = tree[k << 1].val;else tree[k].val = -1; }void cal(int k) {if (tree[k].val>0) {ans.insert(tree[k].val);return;}if (!tree[k].val) return;cal(k << 1);cal((k << 1) | 1); }int main() {cin >> T;while (T--) {cin >> n;ans.clear();num.clear();for (int i = 1; i <= n; i++) {scanf("%d%d", &loc_[i].u, &loc_[i].v);//讀入最初的數(shù)據(jù)、//把所有的點(diǎn)整合在一起 num.push_back(loc_[i].u);num.push_back(loc_[i].v);//保證連續(xù)性num.push_back(loc_[i].u + 1);num.push_back(loc_[i].v + 1);}sort(num.begin(), num.end());vector<int>::iterator iter = unique(num.begin(), num.end());//去重//得到新的范圍for (int i = 1; i <= n; i++) {loc[i].u = lower_bound(num.begin(), iter,loc_[i].u) - num.begin();loc[i].v = lower_bound(num.begin(), iter, loc_[i].v) - num.begin();loc[i].u++;loc[i].v++;}built(1, M, 1);for (int i = 1; i <= n; i++) {x = loc[i].u, y = loc[i].v, z = i;change(1);}cal(1);cout << ans.size() << endl;}return 0; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/caibingxu/p/10805640.html

總結(jié)

以上是生活随笔為你收集整理的POJ - 2528 线段树+离散化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。