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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HihoCoder - 1483 区间最值

發(fā)布時(shí)間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HihoCoder - 1483 区间最值 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

給定n個(gè)數(shù)A1...An,小Ho想了解AL..AR中有多少對元素值相同。小Ho把這個(gè)數(shù)目定義為區(qū)間[L,R]的價(jià)值,用v[L,R]表示。

例如1 1 1 2 2這五個(gè)數(shù)所組成的區(qū)間的價(jià)值為4。

現(xiàn)在小Ho想知道在所有的的v[L,R](1 <= L <= R <= n)中,第k小的值是多少。

Input

第一行一個(gè)數(shù)T(T<=10),表示數(shù)據(jù)組數(shù)。

對于每一組數(shù)據(jù):

第一行兩個(gè)數(shù)n,k(1<=n<=200,000,1<=k<=n*(n+1)/2)

第二行n個(gè)數(shù)A1…An(1<=Ai<=1,000,000,000)

Output

一個(gè)數(shù)表示答案。

Sample Input

2 4 7 1 1 2 3 3 6 100 100 100

Sample Output

0 3

題意:我們給出n個(gè)數(shù),我們求任意一段區(qū)間,他們相同的數(shù)的次數(shù)就是區(qū)間的值,然后我們按值排序求第k個(gè)區(qū)間的值是多少

思路:開始我用的n2,果斷超時(shí)。。然后我們看到ai的范圍有這么大,我們又要記錄次數(shù),顯然我們可以用map,但是我用map也超時(shí)了,
所以有個(gè)高級的操作,因?yàn)閚的范圍數(shù)組能開的下,只是ai值大而已,所以我們可以離散化,然后我們想一下,怎么求答案呢,如果我們直接求出所有的區(qū)間再排序輸出的話n2復(fù)雜度
所以發(fā)現(xiàn)不行,我們仔細(xì)想想,我們能得知我們區(qū)間長度越小,我們的區(qū)間值肯定更小,我們可以二分去處理,二分的話最小值是0沒有一個(gè)相同,最大的時(shí)候也就是全部的數(shù)都相同,可以推出是n*(n-1)/2
因?yàn)槲覀円笫乔蟮趉個(gè)區(qū)間的值,那么我們就只要去尋找判斷,小于當(dāng)前數(shù)的區(qū)間個(gè)數(shù)有多少個(gè),如果小于這個(gè)數(shù)的區(qū)間比k還大的話,說明我們當(dāng)前的數(shù)肯定比我們要求的小,所以我們向右擴(kuò)展,反之亦然

然后我們想如何去求多少個(gè)區(qū)間比他小呢?
我們可以不用求出所有區(qū)間的值為什么呢,因?yàn)槲覀儏^(qū)間的個(gè)數(shù)和值的大小息息相關(guān)
如果[l.r]是比k小的,那么[l,r-1],[l,r-2]....[l,l]都是小于k的數(shù),這里就用到了我們的尺取法
那么我們就把它變成了一個(gè)nlogn的算法

#include<cstdio> #include<cmath> #include<cstring> #include<map> #include<algorithm> using namespace std; typedef long long ll; ll a[200001]; ll t,n,m,temp[200001]; ll vis[200001]; ll check(ll mid)//尺取求比mid小的區(qū)間個(gè)數(shù) {int i,j;ll sum=0;ll num=0;memset(vis,0,sizeof(vis));for(i=0,j=0;i<n;i++){for(;j<n&&sum+vis[a[j]]<=mid;j++){sum+=vis[a[j]];vis[a[j]]++;}num+=j-i;//尺取思想核心vis[a[i]]--;sum-=vis[a[i]];}return num>=m; } int main() {ll ans;scanf("%lld",&t);while(t--){scanf("%lld%lld",&n,&m);for(int i=0;i<n;i++){scanf("%lld",&a[i]);temp[i]=a[i];}int cnt;sort(temp,temp+n);//離散化cnt = unique(temp,temp+n) - temp;for(int i = 0 ; i < n ; ++i)a[i] = lower_bound(temp,temp+cnt,a[i]) - temp;ll left=0,right=((ll)n*((ll)n-1))/2;while(left<=right){ll mid=(left+right)/2;if(check(mid))//如果小于mid的區(qū)間個(gè)數(shù)比m多的話,說明值還不夠小{ans=mid;right=mid-1;}else{left=mid+1;}}printf("%lld\n",ans);} }

?

轉(zhuǎn)載于:https://www.cnblogs.com/Lis-/p/9393788.html

總結(jié)

以上是生活随笔為你收集整理的HihoCoder - 1483 区间最值的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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