洛谷 1110 報表統計 線段樹

2021-10-07 08:14:55 字數 3556 閱讀 8875

題解:

考慮離散化,利用兩顆線段樹來維護合適的資訊求解兩個詢問。

min_gap:求相鄰的差值絕對值最小。建立線段樹儲存差值的出現次數,詢問時求差值最小的那個即可。記位置i

ii初始值為a[i

]a[i]

a[i]

,新插入的值為b[i

]b[i]

b[i]

(初始b[i

]=a[

i]

b[i]=a[i]

b[i]=a

[i]),當在位置i

ii插入乙個新的數k

kk時,原本的差值abs

(a[i

+1]−

b[i]

)abs(a[i+1]-b[i])

abs(a[

i+1]

−b[i

])出現次數減一,新出現兩個差值abs

(b[i

+1]−

k),a

bs(k

−b[i

])

abs(b[i+1]-k), abs(k-b[i])

abs(b[

i+1]

−k),

abs(

k−b[

i])出現次數加1(注意一下i==

ni == n

i==n

時,只需更新第乙個)。然後另b[i

]=

kb[i] = k

b[i]=k

即可。min_sort_gap:求最接近的兩個元素的差值。線段樹維護數出現的次數即可。設ans

2ans2

ans2

,初始為原陣列中排序後相鄰元素差值的最小值。更新時,統計≤

k\le k

≤k的數的數量sum,求第sum

,sum

+1

sum,sum+1

sum,su

m+1個元素的值,與k

kk求差值,更新ans

2ans2

ans2

即可。ans

2ans2

ans2

即結果。最後將k的資訊放入線段樹。若ans

2==0

ans2 == 0

ans2==

0後,差值不會更小,則停止查詢更新的操作,以降低時間複雜度。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define dbg(x) cout<<#x<<" = "<#define inf 0x3f3f3f3f

#define llinf 0x3f3f3f3f3f3f3f3f

#define eps 1e-6

using namespace std;

typedef

long

long ll;

typedef pair<

int,

int> p;

const

int maxn =

2500100

;const

int mod =

10000

;int a[maxn]

, b[maxn]

, c[maxn]

, p1[maxn*3]

, p2[maxn*3]

;int op[maxn]

, x[maxn]

, y[maxn]

;int

lisan

(int n,

int a)

;void

update

(int l,

int r,

int x,

int y,

int k,

int p)

;int

querysum

(int l,

int r,

int x,

int k,

int p)

;int

query

(int l,

int r,

int x,

int k,

int p)

;int

main()

sort

(c+1

, c+

1+n)

;for

(i=2

;i<=n;i++

)ans2 =

min(ans2, c[i]

-c[i-1]

);cnt = n;

for(i=

2;i<=n;i++

)c[++cnt]

=abs

(a[i]

-a[i-1]

);for(i=

0;i)else

if(str[4]

=='g'

)op[i]=2

;else op[i]=3

;}for(i=

1;i<=n;i++

)b[i]

= a[i]

; cnt =

lisan

(cnt, c)

;for

(i=1

;i<=n;i++

)for

(i=0

;i(op[i]==1

)update(1

, cnt, pos,1,

1, p1);}

int ch =

abs(y[i]

-b[x[i]])

; pos =

lower_bound

(c+1

, c+

1+cnt, ch)

-c;update(1

, cnt, pos,1,

1, p2);if

(x[i]

!= n)

}else

if(op[i]==2

)printf

("%d\n"

, c[

query(1

, cnt,1,

1, p2)])

;else

printf

("%d\n"

, ans2)

;return0;

}int

lisan

(int n,

int a)

void

update

(int l,

int r,

int x,

int y,

int k,

int p)

intquerysum

(int l,

int r,

int x,

int k,

int p)

intquery

(int l,

int r,

int x,

int k,

int p)

洛谷P1110 報表統計 平衡樹 堆

在最開始的時候,有乙個長度為n n的整數序列,並且有以下三種操作 首先操作三是很簡單的,我們只要寫一棵平衡樹,維護每乙個數字的前驅後繼,每次插入乙個數就判斷它與它前驅後繼的差值是否小於min nmin n。如果小於就更新。對於第二問,定義las t i last i 表示原序列第i i個數字後面插入...

洛谷 3373 線段樹

傳送門 思路 關鍵在於乘與加的先後計算關係,x y k x k y k,從這裡可以看出來,把加法轉化為乘法計算,取消了 與 先後順序 pushdown時,即為乘法標記 原有資料 加法標記 長度。注意點 這個題資料範圍取long long 讀入的k也是long long,傳入函式時用long long...

洛谷 1198 線段樹

線段樹的單點更新 區間查詢,典型的求區間最大值。如下 1 include2 using namespace std 3 typedef unsigned int ui 4 typedef long long ll 5 typedef unsigned long long ull 6 define p...