求區間不同數字的個數和和

2021-10-01 01:49:21 字數 2575 閱讀 5486

1 byte = 8 bit

1 kb = 1,024 bytes

1 mb = 1,024 kb = 1,048,576 bytes

乙個int是4位元組即4byte.

求個數和求和類似,不過是在更新的時候把1變成了這個數的值,下面就講講求區間不同數字的個數。

首先我們思考對於右端點固定的區間(即r確定的區間),我們如何使用線段樹來解決這個問題。

我們可以記錄每個數字最後一次出現的位置。比如,5這個數字最後一次出現在位置3上,就把位置3記錄的資訊++(初始化為0)。比如有乙個序列 1 2 2 1 3  那麼我們記錄資訊的數列就是 0 0 1 1 1 (2最後出現的位置是位置3  1最後出現的位置是位置4  3最後出現的位置是位置5)。那麼對區間 [1,5] , [2,5] , [3,5] , [4,5] , [5,5]的數字種數,我們都可以用sum[5]-sum[x-1]來求(sum陣列記錄的是字首和)(字首和之差可以用線段樹或者樹狀陣列來求)。

那麼對著區間右端點會變化的題目,我們應該怎麼辦呢?先思考一下如果右端點有序的話,我們可以怎麼做。對r不同的區間,向線段樹或者樹狀陣列中新增元素,知道右端點更新為新的r,在新增的過程中,如果這個元素之前出現過,就把之前記錄的位置儲存的資訊 -1,然後在新的位置儲存的資訊 +1,這樣就可以保證在新的右端點固定的區間裡,記錄的是數字最後一次出現的位置的資訊,這樣題目就解決了。

也就是說對於這個題目,我們也可以不用主席樹,只要對詢問排序,然後利用樹狀陣列或者線段樹就可以解決這個問題。(離線解法

給你 n 個數,然後有 q 個詢問,每個詢問會給你[l,r],輸出[l,r]之間有多少種數字。

#include//主席樹

using namespace std;

#define ll long long

#define ****(x) cout<<#x<<" "this->rs=rs;

this->sum=sum;

}}tree[maxn*30];

int build1(int l,int r)

return t;

}int build2(int l,int r,int last,int pos,int val)

return t;

}int query(int l,int r,int l,int r,int t)

return ans;

}int main()

vis[a[i]]=i;

}while(q--)

return 0;

}

hdu3333-turing tree

給一段n長度的數字序列,以及q次區間詢問,問區間不同數字大小之和。

#include//主席樹

using namespace std;

#define ll long long

#define ****(x) cout<<#x<<" "this->rs=rs;

this->sum=sum;

}}tree[maxn*40];

inline int getid(int x)

int build1(int l,int r)

return t;

}int build2(int l,int r,int last,int pos,int val)

return t;

}ll query(int l,int r,int l,int r,int t)

return ans;

}int main()

vis[newid]=i;

}//****(3);

scanf("%d",&q);

while(q--)

//****(4);

}return 0;

}

#include//線段樹

using namespace std;

#define ls rt<<1

#define rs (rt<<1)+1

#define ****(x) cout<<#x<<" "<>1;

if(pos<=mid)

update(ls,l,mid,pos,val);

else

update(rs,mid+1,r,pos,val);

}}ll query(int rt,int l,int r,int l,int r)

return ans;

}int main()

sort(qy+1,qy+q+1);

for(int i=1;i<=q;i++)

vis[newid]=now++;

}ans[qy[i].id]=query(1,1,n,qy[i].x,qy[i].y);

}for(int i=1;i<=q;i++)printf("%lld\n",ans[i]);

}return 0;

}

區間不同數個數

開坑.最近要把朱熹樹寫一下,就開個大坑來記錄我的腦洞吧 給定乙個序列,給出一些對於某個區間 l,r 的詢問,求這個區間內不同數的個數.int seq rangequery define input classof int n,m fon i,n seq i fon i,m query i n def...

樹樁陣列維護區間不同值的個數

題目 結果只有80分,不夠學了一招。將問題轉化為離線問題。我們先將詢問按右節點公升序排序。然後對於每乙個值,我們可以肯定的是,只有最靠近詢問右端的值才可能起作用。case 1 如果詢問不包括某個值。那麼這個值,對答案沒有影響 case 2 包括的話,那麼至少包括1個這樣的值,而我們詢問的是不同的個數...

查詢任意區間內不同元素的個數

include using namespace std define ll long long const int maxn 2e5 5 const int mod 1e9 7 const double eps 1e 9 const double pi acos 1.0 const int inf ...