題目鏈結
題目意思很簡單,給出乙個長度為n的陣列、m個查詢;每個查詢有 l ~ r 查詢的是區間裡的眾數,如果數量相等輸出小的那個。
這可怎麼做,?
剛開始看到這道題、懵了一會、想不到怎麼做;線段樹沒辦法維護或者是我不會維護 感覺 咋咋都不行
於是看了看書上的題解,看不懂啊 只看懂了要用分塊;
於是就自己想著用分塊寫。。。結果我很菜沒寫出來,(又t又wa)
於是網上找部落格看,終於 a 了,
好了不說廢話了hhhhhhh
題解:
分塊的思想,把這些數分成一塊一塊 然後暴力
首先這些數1e9 如果要用陣列存個數 肯定是要離散化的。
然後 離散化完呢? 既然已經把他們分塊了,那麼要查詢的那個答案肯定是大段+小段合併得到的
於是想想怎麼得到?
看看這個歪歪扭扭的圖
大段是d2 小段是d1 - d2
那麼這個區間的眾數肯定是在d2裡的眾數和d1 - d2 裡的所有數里的(很他媽關鍵我咋就想不到 )
於是得維護乙個d2 的眾數 也就是維護一段連續的大段的眾數
這個簡單暴力就好
然後 最後知道了答案在那些數里 可是怎麼去找答案?
也就是要統計查詢的 l ~ r 裡那些數的個數。
怎麼統計? for一遍肯定是不行的。
這裡也是我所想不到的;
用乙個vector[maxn] 二維陣列 存每個數字出現的地方,於是這個數字出現的次數就是:upper_bound( vp[x].begin() , vp[x].end() , r ) - lower_bound( vp[x].begin(), vp[ x ].end() , l ) ;
這個很顯然,因為vector是有序的。
附上**:
#include
#include
#include
#include
#include
using
namespace std;
vector<
int> vv;
const
int maxn =
4e4+5;
const
int n =
805;
vector<
int> vp[maxn]
;int bj[maxn]
;int zs[n]
[n];
int a[maxn]
;int l[maxn]
;int r[maxn]
;int vis[maxn]
;int n;
int temp[maxn]
;void
init()
if(r[t]
< n)
for(
int i =
1; i <= t; i ++)}
for(
int i =
1; i <= t; i++
) zs[i]
[vis[j]
]= ans;
}for
(int j =l[i]
; j <= n; j ++)}
}set<
int> ss;
intgetnum
(int l,
int r,
int x)
int tt[maxn]
;int
getans
(int l,
int r)
for(
int i = l[q]
; i <= r; i ++
)int ss =
unique
(tt,tt+kk)
- tt;
int num =0;
int ans =0;
for(
int i =
0; i < ss; i ++)}
// printf("\n");
return ans;
}int
main()
sort
(vv.
begin()
,vv.
end())
; vv.
erase
(unique
(vv.
begin()
,vv.
end())
,vv.
end())
;for
(int i =
1; i <= n; i ++
)for
(int i =
1; i <= n; i ++
)init()
;int x =0;
while
( m --
)}
AcWing249 蒲公英 分塊
題意 解法分塊。首先,一段區間的眾數的候選答案一定是大塊的眾數或者小塊的每乙個數,先預處理出大塊的眾數,這樣候選答案的範圍就縮小到了 n sqrt n n 個,然後每個再詢問區間內出現的次數,維護答案即可。但是這樣做這題是無法通過所有測試點的,考慮優化查詢部分,可以預處理每個數在所有塊 現次數的字首...
蒲公英 分塊
在鄉下的小路旁種著許多蒲公英,而我們的問題正是與這些蒲公英有關。為了簡化起見,我們把所有的蒲公英看成乙個長度為 n 的序列a1,a2,an,其中ai為乙個正整數,表示第 i 棵蒲公英的種類編號。而每次詢問乙個區間 l,r 你需要回答區間裡出現次數最多的是哪種蒲公英,如果有若干種蒲公英出現次數相同,則...
分塊 蒲公英
include include include include define maxn 40005 using namespace std int rd return x partition section int a maxn blk maxn sizb int tmplwb maxn 離散化的輔...