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