題意: 區間價值為 區間元素種類數 / 區間長度 問最小價值的區間是?
思路:直接求解很困難,考慮二分答案判斷,注意這題的關鍵是將二分答案後的不等式進行變換,如官方題解。二分答案 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...