CodeChef LNDNCK 回滾莫隊

2021-10-08 11:48:49 字數 3430 閱讀 3096

鏈結

給你兩個陣列, b, p, 陣列個數n 小於等於 2e5.

m 個詢問, 每次詢問 l r, 把 區間 [l, r] 按照 b 的公升序排序, 然後求和 abs(p[i] - p[i-2]).

一開始的思路就是直接暴力莫隊,

每次把 b 插入到map 裡面去, 刪除也是直接從 map 裡面刪除。

每次修改只會影響周圍的幾個值。

但是每次map 的查詢是 log 的, 會超時。

所以要想乙個方法, 每次查詢時 o(1) 的。

這個時候用回滾莫隊。

用乙個鍊錶把 b 從小到大串起來。 只有 刪除的操作, 然後每次回滾。

在操作每乙個塊的時候, r 設定成 n, l 設定成 塊的左端點。

然後 r 不斷減小, 每次詢問結束,l 會重新回滾到 塊的左端點。

刪除乙個節點就是把這個節點的左右節點連起來。

回滾乙個節點就是在把這個節點加進去。

這裡有個不開結構體然後排序的東西,

就是 b 陣列, p 陣列,要跟著b陣列排序。

直接另開乙個 index 陣列, 用下標排序, cmp 裡面寫這 b 的關係就好了.

inline

bool

cmp(

int i,

int j)

for(re i = n; i >=1;

--i)

一開始用的時鍊錶, 每次 new , 很廢時間。

用鍊錶的時候,用 unordered_map 存的每乙個節點。

後來棄了鍊錶,直接用陣列模擬鍊錶。 也沒有用 map 存node 的位置。

分塊的時候, 用的時 n 的 2/3 次方, ***, 這就是個坑, 應該用sqrt(n), 部落格害人。

#include

#define mem(a,b) memset(a,b,sizeof a);

#define rep(i,a,b) for(register int i = a; i <= b; i++)

#define per(i,a,b) for(register int i = a; i >= b; i--)

#define re register int

typedef

long

long ll;

typedef

double db;

const

int n =

2e5+

100;

using

namespace std;

int a[n]

, pos[n]

, n, m, l[n]

, r[n]

, b[n]

, p[n]

,blocks,idx[n]

;ll ans[n]

, ans;

struct node

}q[n]

;struct nodef[n]

;inline

intread()

return x;

}void

out(ll x)

inline

bool

cmp(

int i,

int j)

void

init()

for(re i =

1; i <= blocks;

++i)

for(re j = l[i]

; j <= r[i]

;++j)

pos[j]

= i;

// 為每個位置分配塊。

rep(i,

1,n)

idx[n+1]

= n+1;

ans =0;

sort

(idx+

1,idx+n+

1,cmp)

;

f[0]

.val =0;

f[n+1]

.val =-1

;for

(re i = n; i >=1;

--i)

m =read()

;rep

(i,1

,m)sort

(q+1

,q+1

+m);

}void

add(

int x)

void

del(

int x, ll &tmp)

if(f[it1.pre]

.val != f[0]

.val)

it2 = f[it2.nxt];if

(it2.val != f[n+1]

.val)

if(it2.val != f[n+1]

.val) x4 = it2.val;

if(x1 !=-1

) tmp -

=(ll)

abs(x - x1);if

(x4 !=-1

) tmp -

=(ll)

abs(x - x4);if

(x3 !=-1

&& x2 !=-1

) tmp -

=(ll)

abs(x3-x2);if

(x1 !=-1

&& x3 !=-1

) tmp +

=(ll)

abs(x1-x3);if

(x4 !=-1

&& x2 !=-1

) tmp +

=(ll)

abs(x4-x2)

; f[it3.nxt]

.pre = it3.pre;

f[it3.pre]

.nxt = it3.nxt;

}void

solve()

while

(r > q[i]

.r)del

(r--

, ans1)

; ans2 = ans1;

// ans1 的值不能動, 因為詢問之後, l 會重新回退到這個位置,

while

(l < q[i]

.l) ans[q[i]

.id]

= ans2;

while

(l > l[pos[q[i]

.l]]

)add

(--l);}

rep(i,

1,m)

out(ans[i]),

puts(""

);}int

main()

/*62 14 6

1 43 10

6 45 8

51 2

1 3

1 4

1 5

1 6 215

1080*/

ServletOutputStream回寫頁面亂碼

一段utf 16的string,整了好多種格式,硬是無法正確輸出到頁面上 首先嘗試了outputstream,即便指定string byte的編碼,還是出錯 resp.getoutputstream write out.getbytes utf 16 resp.getoutputstream pri...

頁面回發和事件回傳

客戶端 瀏覽器 客戶端事件 傳送資料 資料 服務端 引發伺服器端事件處理程式 處理資料 處理完畢,重新形成 html 傳送 html 客戶端 瀏覽器 展示 頁面回發包含了 頁面第一次傳送到客戶端引起的 not ispostback 和客戶端事件 事件回傳 引起的頁面回發 上面的圖就是頁面回發的示意圖...

語音回呼api 發起回呼

語音回呼api 可以快速建立起訪客與 主之間的 連線,讓訪客更加輕鬆的與 主進行對話 諮詢 洽談等,發起呼叫,未接通不計費,0.0825元 分鐘。介面名稱 語音回呼api 介面平台 聚合資料 支援格式 json 請求方式 http get 請求示例 您申請的 key phone 1891231353...