51nod 第K大區間2(二分 樹狀陣列)

2022-04-07 11:40:34 字數 1698 閱讀 6145

定義乙個長度為奇數的區間的值為其所包含的的元素的中位數。

現給出n個數,求將所有長度為奇數的區間的值排序後,第k大的值為多少。

樣例解釋:

[l,r]表示區間的值

[1]:3

[2]:1

[3]:2

[4]:4

[1,3]:2

[2,4]:2

第三大是2

input第一行兩個數n和k(1<=n<=100000,k<=奇數區間的數量)

第二行n個數,0<=每個數<2^31output乙個數表示答案。input示例43

3124output示例2

二分答案t,統計中位數大於等於t的區間有多少個。

設a[i]為前i個數中有a[i]個=t,若奇數區間[l,r]的中位=t,則(a[r]-a[l-1])*2>r-l+1,即(a[r]*2-r)>(a[l-1]*2-l+1)。

設b[i]=a[i]*2-i,統計每個b[i]有多少個b[j]總複雜度o(nlognlogn)

二分就不用說了。至於a和b,用法講的也挺明白。就是統計b[j] < b[i]那一步,可以用樹狀陣列處理,注意a[i]*2-i可能為負值(當n個數從小到大有序時 t == 最大數時,a[n] = -n

因此需要+n避免越界

**如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define pr pair

#define fread() freopen("in.in","r",stdin)

#define fwrite() freopen("out.out","w",stdout)

using namespace std;

const int inf = 0x3f3f3f3f;

const int msz = 32768;

const int mod = 1e9+7;

const double eps = 1e-8;

int num[100100];

int tmp[100100];

int a[100100],bit[2][400400];

int tp,n;

int lowbit(int x)

void add(int pos,int x)

}int sum(int pos,int x)

return ans;

}ll cal(int pos)

else

//printf("ans:%lld\n",ans);

}//printf("ans:%lld\n",ans);

return ans;

}int main()

sort(tmp,tmp+n);

tp = unique(tmp+1,tmp+n+1)-tmp;

int l,r,ans;

l = 1,r = tp-1;

while(l <= r)

printf("%d\n",tmp[ans]);

return 0;

}

51NOD 1686 第K大區間 二分

第k大區間 定義乙個區間的值為其眾數出現的次數。現給出n個數,求將所有區間的值排序後,第k大的值為多少。input 第一行兩個數n和k 1 n 100000,k n n 1 2 第二行n個數,0 每個數 2 31 output 乙個數表示答案。input示例 4 2 1 2 3 2 output示例...

51nod 1686 第K大區間 二分 尺取

題意 定義乙個區間的值為其眾數出現的次數。現給出n個數,求將所有區間的值排序後,第k大的值為多少。思路 答案具有單調性,所以可以二分,關鍵是check的時候怎麼統計有多少區間滿足 mid,我們可以知道假如區間 l,r 滿足,那麼左右擴大這個區間都是滿足的,所以可以尺取,列舉右端點,找到最大的符合條件...

51 nod 1686 第K大區間(二分 尺取)

定義乙個區間的值為其眾數出現的次數。現給出n個數,求將所有區間的值排序後,第k大的值為多少。input第一行兩個數n和k 1 n 100000,k n n 1 2 第二行n個數,0 每個數 2 31output乙個數表示答案。sample input4 2 1 2 3 2sample output2...