SPOJ DQUERY (主席樹求區間不同數個數)

2022-08-05 17:36:13 字數 850 閱讀 4738

題意:找n個數中無修改的區間不同數個數

我們需要這麼想:從左向右新增一到主席樹上,新增的是該數字處在的位置

但是如果該數字前面出現過,就在此版本的主席樹上的前面出現的位置減一,接著才在此位置上添一

這樣查詢是按照右區間版本的主席樹來找(lef,rig)的數字

因為要將此區間每個不同的數都處在最後出現的位置

/*

如果此數之前出現過就先減去,接著再加,最後在區間(l,r)中找到root[r]這個歷史版本

*/#include

#include

#include

#include

using

namespace

std;

#define dir(a,b) (a>>b)

const

int max=30010

;int

root[max],tot,val[max];

struct

node

msegtr[max*40

];map

mp;void

init()

void create(int sta,int enn,int &x,int y,int pos,int

aad)

int query(int sta,int enn,int x,int y)//

只有左邊有界限

intmain()

else

mp[val[i]]=i;

}scanf("%d

",&m);

for(int i=0;ii)

}return0;

}

SPOJ DQUERY 主席樹 lazy 亂搞

題意要求a,b區間中不同數的個數。我們從頭往後掃,對於前面已經出現過的我們不用管,因為我們現在要的是加入掃到p這個店就求以這個點為結尾的查詢,至於之前已經出現過的加入出現在q,那麼得在q p 1每個數減一用lazy維護。include include include include include ...

SPOJ DQUERY 離線樹狀陣列or主席樹

給出n個數,問區間 l,r 中有多少不同的數。經典題。可以離線 樹狀陣列,離線儲存查詢,按照r排序,用last陣列儲存每個數最接近當前詢問r的位置。也可以主席樹,從右到左建樹,pos儲存每個數字的當前最左位置,每次在新版本的線段樹中在當前位置 1,然後把舊版本中該樹的位置 1.離線 樹狀陣列 inc...

主席樹求區間第k大

主席樹是可持久化線段樹,維護 權值個數 線段樹的字首和。相當於對每個區間 1,i 建立n顆線段樹。我們用乙個區間內的數的出現個數建線段樹,所以資料大小較大時一般進行離散化。建的是權值線段樹,即用數值作為區間,每個節點存該數出現的次數,所以query返回的其實是離散後的陣列b的下標idx,最終結果為b...