洛谷P1972 HH的項鍊

2022-04-05 23:26:32 字數 1566 閱讀 1641

傳送門啦

分析:

題目描述不說了,大意是,求一段區間內不同元素的種數。

看到區間,我們大概先想到的是暴力(然後炸掉)、線段樹、樹狀陣列、分塊。

下面給出的是一種樹狀陣列的想法。

首先,對於每一段區間裡的數,如果出現重複的元素,我們只需要看最後乙個就好了。所以,我們可以對所有需要查詢區間的右端點進行從小到大的排序,從左往右列舉右端點維護乙個從左向右的樹狀陣列,表示一段區間的種類數。

聽不懂的話我們舉個栗子例子。

我們假設現在有乙個序列:

now為現在的右端點;

insert(i , j)表示在第i個位置出現了j個位重複的數,就需要我們在我們維護的樹狀陣列序列中+j。

1 ,2 ,1 ,3

當now = 1時,insert(1 , 1),樹狀陣列對應的序列就變成了1,0,0,0

當now = 2,insert(2,1),序列變成了1,1,0,0

當now = 3時,我們發現a[3]=1,而1之前已經出現過了,所以最後一次出現的地方(a[1])減1,即insert(1,−1),a[3]這個地方加1,即insert(3,1),序列變成了0,1,1,0

當now = 4時,insert(4 , 1),序列變成0,1,1,1

這樣的話,我們列舉ii的時候處理一下就ok了.

最後whilewhile輸出sum[ ](類似字首和的乙個陣列如果查詢區間[3~5],就變成sum[5]−sum[2])。

你會發現**中還有乙個last[ ],last[i]根據我的解釋應該很好懂吧,表示的就是ii這個元素最後出現的位置。。

好了,**奉上。。

#include #include 

#include

#include

using

namespace

std;

const

int maxn = 1000005

;inline

intread()

while(ch >= '

0' && ch <= '9')

return x *f;

}int

n,a[maxn],m;

struct

edgee[maxn

<< 2

];int

last[maxn],sum[maxn],ans[maxn];

inttmp;

bool cmp(edge a,edge b)

int lowbit(int x)

void insert(int x,int

v)int query(int

x)int

main()

sort(e + 1 , e + 1 +m , cmp);

int now = 1

;

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

}for(int i=1;i<=m;i++)

printf(

"%d\n

",ans[i]);

return0;

}

洛谷 P1972 HH的項鍊

題意 查詢某一區間顏色數 思路 對於固定區間來說,顏色數隻與各種顏色第一次出現的位置有關。該位置置1,該顏色其餘位置置0.include using namespace std typedef long long ll typedef pairpii typedef pairpiii const l...

洛谷P1972 HH的項鍊 樹狀陣列

題目 題意 給定乙個長度為n的序列,數字表示珠子的種類。m次查詢每次詢問給定區間內珠子的種類數。思路 可以說是運用了字首和的思想吧。從前到後的去處理查詢,而對於某乙個查詢區間,如果某乙個種類出現了多次的話我們只需要計算最後一次出現。用query x 表示1 x區間內的種類數,其中對每個種類我們只標記...

樹狀陣列 洛谷 P1972 HH的項鍊

hh 有一串由各種漂亮的貝殼組成的項鍊。hh 相信不同的貝殼會帶來好運,所以每次散步完後,他都會隨意取出一段貝殼,思考它們所表達的含義。hh 不斷地收集新的貝殼,因此,他的項鍊變得越來越長。有一天,他突然提出了乙個問題 某一段貝殼中,包含了多少種不同的貝殼?這個問題很難回答 因為項鍊實在是太長了。於...