hdu3333 線段樹,離散化,離線操作

2021-09-26 08:37:36 字數 1550 閱讀 6904

求區間不同數字的和;

先將資料離散化,離線操作就是要先將問題儲存起來,根據一定的順序解答來降低複雜度;

這題就將問題儲存起來後按右邊界排序,之後從左到右逐個點的建立線段樹,同時標記一下這個值是否出現過和位置,如果之前出現過,就把之前出現的點清零再在當前點插值,同時看當前的點有沒有剛剛排好序的問題的右邊界,如果遇到了,就對這個問題求和,因為之前的數已經去過重並且都是最靠右的,所以對這個區間求和的答案是正確的;然後繼續更新下乙個節點…

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

typedef

unsigned

long

long ull;

const

int maxn=

30010

;ll num[maxn<<2]

;void

update

(int pos,

int val,

int le,

int ri,

int node)

int t=

(le+ri)

>>1;

if(pos<=t)

update

(pos,val,le,t,node<<1)

;else

update

(pos,val,t+

1,ri,node<<1|

1); num[node]

=num[node<<1]

+num[node<<1|

1];}

ll query

(int l,

int r,

int le,

int ri,

int node)

struct edgeb[maxn*4]

;bool

cmp(edge a,edge b)

int vis[maxn]

,pre[maxn]

,a[maxn]

;ll ans[maxn*4]

;int

main()

cin>>m;

for(

int i=

0;i)scanf

("%d%d"

,&b[i]

.num1,

&b[i]

.num2)

,b[i]

.pos=i;

sort

(b,b+m,cmp)

;對問題排序

for(int i=

0,j=

0;i)else

for(

;j)//對j個詢問作答

}for

(int i=

0;i)printf

("%i64d\n"

,ans[i]);

}}

HDU 3333 線段樹 離散化

只查詢區間不同的數的和 思路好題 對查詢離線 不斷的往每個位置插值 並把前面位置的值置為0 每查到乙個右端點 查詢一下 等價操作的轉換 離散化一下 include define mem a,b memset a,b,sizeof a define lson root 1 define rson ro...

HDU 3333 離線線段樹

線段樹 給定乙個序列,求區間出現的數的數值和,若有多個,只計算一次 先離散化存數資料 對詢問區間按右節點排序,這樣我們每次維護的都是從前到當前位置,保證其重複元素不累加 跟新節點,對於之前出現過的刪除,並在新位置新增 然後查詢即可 include iostream include algorithm...

hdu 3333 離散化 離線操作

若不是題中的數看錯了導致舒陣列開小造成的re,就是1a呀,話說最近總是犯這種錯誤,難道要換眼鏡?一看肯定是線段樹,求區間內不同的數的和,由於這些數要不同,可能不是連續的,所以要離線處理。將訪問操作按照末端節點排序。然後再把a陣列離散化即可。include include define ss a sc...