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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

题解 UVA10587 【Mayor's posters】

發布時間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 题解 UVA10587 【Mayor's posters】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

先講一下:dalao @lisuier 發布的前一篇題解嚴格來講是有錯誤的

比如下一組數據:

1 3 1 10 1 4 7 10 顯然答案是3,然而用lisuier dalao的程序做出來的答案是2(后面會講錯誤原因)

簡單看出這道題用線段樹可解

so

我們用離散化+權值線段樹(戳這里詳解)

實際上是安利自己博客

思路:建一棵空數,然后把某一區間的顏色更新為讀入的顏色;

WA,SO EASY

OK
那我們先建一棵(10^7*4)的空樹

然后

空間就炸了

正經的處理方法

對區間端點進行離散化

接下來
引用一下的 @lisuier 的話

離散化,如下面的例子,因為單位1是一個單位長度,將下面的

1 2 3 4 6 7 8 10

— — — — — — — —

1 2 3 4 5 6 7 8
離散化 X[1] = 1; X[2] = 2; X[3] = 3; X[4] = 4; X[5] = 6; X[7] =8; X[8] = 10
這樣我們就優化了空間

對一般的離散化來說,這很對,

但是

再看這一組數據

1 3 1 10 1 4 7 10

用該方法離散化后

第二張海報與第三張海報中間的間隔就消...消失了

也就是說第一張海報就看不到了(手動模擬一下發現是能看到的)

處理方法:離散化時,加到臨時數組b中的右端點+1也加到臨時數組中

看起來是這樣的

int init(){//讀入并進行離散處理n = read(); tot=0;for(int i = 1;i <= n;i++) a[i].l = read(),a[i].r = read(),b[++tot] = a[i].l,b[++tot] = a[i].r,b[++tot] = a[i].r + 1;//加入右邊的端點+1sort(b + 1,b + tot + 1);int len=unique(b + 1,b + tot + 1) - b - 1;for(int i = 1; i <= n;i++) a[i].l = lower_bound(b + 1,b + len + 1,a[i].l) - b,a[i].r = lower_bound(b + 1,b + len + 1,a[i].r) - b; //下面是正常的離散化return len; //離散化后總共處理多長的墻; }

更新之類的與普通線段樹差不多

但是要注意push_down操作和query操作

比如說詢問時已經訪問過得顏色要標記一下

接下來是

簡單易懂

的代碼.

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define M 20005 using namespace std; inline int read(){char chr=getchar(); int f=1,ans=0;while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}while(isdigit(chr)) {ans=ans*10;ans+=chr-'0';chr=getchar();}return ans*f; } int ans = 0; struct segment { int l,r; }a[10005 << 4]; bool vis[20005 << 4]; struct node {int l,r,val,lazy,sum;int mid(){return l + r >> 1;} }t[M << 4]; int b[20005 << 4],n,tot=0,x,y; int init() {//讀入并進行離散處理n = read(); tot = 0;for(int i = 1;i <= n;i++) a[i].l = read(),a[i].r = read(),b[++tot] = a[i].l,b[++tot] = a[i].r,b[++tot] = a[i].r + 1;sort(b + 1,b + tot + 1);int len=unique(b + 1,b + tot + 1) - b - 1;for(int i = 1; i <= n;i++) a[i].l = lower_bound(b + 1,b + len + 1,a[i].l) - b,a[i].r = lower_bound(b + 1,b + len + 1,a[i].r) - b; return len; //離散化后總共處理多長的墻; } void push_down(int i){if(t[i].val == -1) return;t[i << 1].val = t[i << 1 | 1].val = t[i].val; t[i].val = -1; } void build(int i,int l,int r) {t[i].l = l;t[i].r = r;t[i].val = 0;if(l == r){return;}int m=t[i].mid();build(i << 1,l,m);build(i << 1 | 1,m + 1,r); } void updata(int i,int l,int r,int x) {if(l <= t[i].l && t[i].r <= r){t[i].val = x;return;}push_down(i);int m = t[i].mid();if(l <= m) updata(i << 1,l,r,x);if(r > m)updata(i << 1 | 1,l,r,x); } void query(int i,int l,int r) {if(t[i].val != -1){if(!vis[t[i].val]){vis[t[i].val] = 1;//做標記++ans;}return;}query(i << 1,l,r);query(i << 1 | 1,l,r); }int ask(int l,int r) {memset(vis,0,sizeof(vis));ans = 0;vis[0] = 1;query(1,l,r);return ans; }int main() { int T = read();while(T--){int m=init(); tot=0;//海報染成的顏色build(1,1,m);for(int i = 1;i <= n;i++)updata(1,a[i].l,a[i].r,++tot);printf("%d\n",ask(1,m));}return 0; }

轉載于:https://www.cnblogs.com/zhenglw/p/9507872.html

總結

以上是生活随笔為你收集整理的题解 UVA10587 【Mayor's posters】的全部內容,希望文章能夠幫你解決所遇到的問題。

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