hdu 6070 二分答案 線段樹

2022-08-19 20:15:08 字數 1305 閱讀 3394

題意: 區間價值為    區間元素種類數  /  區間長度    問最小價值的區間是?

思路:直接求解很困難,考慮二分答案判斷,注意這題的關鍵是將二分答案後的不等式進行變換,如官方題解。二分答案 mid,檢驗是否存在乙個區間滿足 size(l,r)/(r−l+1) ≤ mid,也就是 size(l, r) + mid × l ≤mid × (r + 1)。

之後的問題就很好解決了,列舉右端點,開一顆線段樹來維護到當前節點的區間不同數(類似樹狀陣列求區間不同數的想法來加入乙個新點,主要是通過乙個陣列維護上一次出現的位置)+  mid × l ,這樣就可以輕鬆判斷是否存在解了。

**:

#includeusing namespace std;

#define mem(a,b) memset(a,b,sizeof(a))

#define bug puts("bug");

inline int ll(int k)

inline int rr(int k)

inline int mid(int kk1,int kk2)

const int maxn=3e6+10;

struct pr tr[maxn+10];

void pushdown(int k)

}void build(int k,int s,int t,double mi)

build(ll(k),s,mid(s,t),mi);

build(rr(k),mid(s,t)+1,t,mi);

tr[k].sum=min(tr[ll(k)].sum,tr[rr(k)].sum);

tr[k].lazy=0;

}void modify(int k,int s,int t,int x)

pushdown(k);

int mi=mid(l,r);

if(t<=mi) modify(ll(k),s,t,x);

else if(s>mi) modify(rr(k),s,t,x);

else modify(ll(k),s,mi,x),modify(rr(k),mi+1,t,x);

tr[k].sum=min(tr[ll(k)].sum,tr[rr(k)].sum);

}double query(int k,int s,int t)

int a[700000],last[700000],t,n;

int cal(double x)

return 0;

}int main()

printf("%.8f\n",r);

}return 0;

}

hdu6070 線段樹 二分

題意給你乙個區間,讓你找,區間種類數 區間長度最小是多少。思路先公式化簡 size r l 1 mid size l 1 mid r mid mid是二分的值 對於每乙個元素a i 他能影響的區間是,last a i 1 到i last表示這個這個元素上一次出現的位置 他能讓這個區間的種類數 1,由...

線段樹 二分 HDU6070

題目讓我們求type l,r r l 1 的最小,顯然可以用01分數規劃,來二分求最小答案。所以我們從左往右移動端點,來統計種類。線段樹來維護type l,r l mid的值。include using namespace std const int n 1e6 7 const double eps...

HDU 6070題解 二分 線段樹

傳送門 此題的題意不是很清晰,要注意的一點是在區間 l,r 中,預設題目編號最後一次出現的時候是ac的 比如1 2 1 2 3 在區間 1,4 中,第3次提交時ac第1題,第4次提交時ac第2題,故比例為2 4 0.5 所以此問題可以轉化為 給定乙個序列,定義區間 l,r 的值為cn t l,r r...