hdu4866(函式式線段樹)

2021-06-23 05:12:52 字數 1819 閱讀 1217

題意:給n個目標線段,在(x,0)處開始沿y軸射擊目標,最多能擊中前k個,問k個目標距離和。

前幾天學了下主席樹,然後又發現多校裡面正好有這類題,所以就來做一下。

一開始自己的想法是這樣的:以線段的橫座標來建立函式式線段樹,但是各種tle,re,wa,最後實在傷不起了,這裡解釋下為什麼會tle和re,因為如果這樣建線段樹,那麼每次放入一條線段就要成段更新,影響的結點數比較多,所以需要很大的空間,然後查詢時又要遍歷較多的節點,所以導致超時,超記憶體。但是我也看到有人用這種方法過的,但是記憶體卡的非常死,如果用結構體寫線段樹,會超記憶體。

題解的思路:首先按距離x軸的距離建立函式式線段樹(需要離散化),然後依次將線段的2*n個端點插入到線段樹中,左端點+1,右端點+1(實際上是r+1的位置

),表示在[l,r]區間內有一條線段,個人覺得這裡用的很巧妙。然後查詢每個x時,用二分法找到該線段樹中的位置,然後再這棵線段樹上找前k個就可以了。

**如下:

#include#include#include#include#include#include#include#include#include#include#include#define n 100005

#define ll __int64

#define inf 0x77ffffff

#define eps 1e-9

#define pi acos(-1.0)

using namespace std;

int dist[n];

struct node

}dot[2*n];

struct node1

tree[50*n];

int rt[2*n],cur;

int build(int l,int r)

int update(int o,int l,int r,int pos,int v,int val)

int m = (l+r)/2;

if(pos <= m) tree[k].l = update(tree[o].l,l,m,pos,v,val);

else tree[k].r = update(tree[o].r,m+1,r,pos,v,val);

tree[k].num = tree[tree[k].l].num + tree[tree[k].r].num;

tree[k].val = tree[tree[k].l].val + tree[tree[k].r].val;

return k;

}ll query(int o,int l,int r,int k)

int m = (l+r)/2;

if(k <= tree[tree[o].l].num) return query(tree[o].l,l,m,k);

else return tree[tree[o].l].val + query(tree[o].r,m+1,r,k-tree[tree[o].l].num);

}int main()

sort(dist,dist+n);

int tot = unique(dist,dist+n) - dist;//range:1--tot

sort(dot,dot+2*n);

cur = 0;

rt[0] = build(1,tot);

for(i = 0; i < 2*n; i++)

ll pre = 1;

while(m--)

if(pre > p) ans = 2*ans;

printf("%i64d\n",ans);

pre = ans;}}

return 0;

}

HDU 4866 多校1 主席樹 掃瞄線

終於是解決了這個題目了 不過不知道下一次碰到主席樹到底做不做的出來,這個東西稍微難一點就不一定能做得出 離散化 掃瞄線式的建樹,所以對於某個座標二分找到對應的那顆主席樹,即搜尋出結果即可 因為是掃瞄線式的建樹,找到對應的樹之後,就知道該點上面的線段有多少條了 其他就是普通主席樹的操作了 主席樹裡面維...

可持久化線段樹 HDU4866 Shooting

題目鏈結 一些平行於x軸的線段作為射擊目標,每次在x軸上選乙個點向y軸方向射擊,可以射中最近的k個目標,得分是射中目標的高度和,求這個得分。對高度建立函式式線段樹,按順序對x軸座標建樹,維護區間和和區間個數,每次射擊詢問該線段樹即可。include include include include i...

tyvj4866 擺攤 線段樹MEX

真的感覺自己real弱啊 在zhx的 幫助下理解了這個內容 我不知道自己這麼低的智商未來會不會有出路 有一些必要的解釋,放在了程式中 next i 0 表示 在序列a中下標為i 1到m中最近一次出現a i 1的位置 關於這個線段樹的使用 線段樹其實我們是查詢截至到右端點,我們現在可用的最小值 我每次...