SPOJ DQUERY 主席樹 lazy 亂搞

2021-06-29 16:54:06 字數 1142 閱讀 2124

題意要求a,b區間中不同數的個數。

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

#include#include#include#include#include#includeusing namespace std;

const int maxn=30015;

struct pipp[maxn*20];

int root[maxn],tot;

void build(int cnt,int le,int ri)

void merg(int qq,int cnt,int n,int p,int k)

else

}}int a[maxn],b[maxn];

struct ppipp1[maxn*10];

struct pppipp2[maxn<<2];

void build1(int tot,int le,int ri)

void merg1(int tot,int l,int r,int k)

int mid=(pp2[tot].le+pp2[tot].ri)/2;

pp[tot].sum+=k*(min(r,pp2[tot].ri)-max(l,pp2[tot].le)+1);

if(l<=mid) merg1(2*tot,l,r,k);

if(r>mid) merg1(2*tot+1,l,r,k);

}int query1(int tot,int l,int r)

int s=0,mid=(pp2[tot].le+pp2[tot].ri)/2;

if(l<=mid) s+=query1(2*tot,l,r);

if(r>mid) s+=query1(2*tot+1,l,r);

s+=pp2[tot].lazy*(min(pp2[tot].ri,r)-max(pp2[tot].le,l)+1);

return s;

}int c[maxn*10];

int cmp(ppi a,ppi b)

sort(b+1,b+1+n);

for(i=1;i<=n;i++)

cin>>m;

for(i=0;i

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

題意 找n個數中無修改的區間不同數個數 我們需要這麼想 從左向右新增一到主席樹上,新增的是該數字處在的位置 但是如果該數字前面出現過,就在此版本的主席樹上的前面出現的位置減一,接著才在此位置上添一 這樣查詢是按照右區間版本的主席樹來找 lef,rig 的數字 因為要將此區間每個不同的數都處在最後出現...

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

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

SPOJ D query 可持久化線段樹

題目描述 多次詢問乙個區間內不同數的數量。解題思路 乙個區間內存在相同的數,所以我們的線段樹就不能維護數,應該去維護下標?為什麼去維護下標呢,就算乙個數相同,但是它們的下標肯定是不同的,我們的線段樹維護下標存在的情況。如果區間內存在重複的數,意味著不同下標對應相同的數,如果我們記錄多個下標答案就會重...