定義乙個長度為奇數的區間的值為其所包含的的元素的中位數。
現給出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...