題意:找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...