6278 數列分塊入門 2

2022-05-06 15:39:11 字數 1463 閱讀 5938

題目描述

給出乙個長為 nn 的數列,以及 nn 個操作,操作涉及區間加法,詢問區間內小於某個值 xx 的元素個數。

輸入格式

第一行輸入乙個數字 nn。

第二行輸入 nn 個數字,第 ii 個數字為 a_iai​,以空格隔開。

接下來輸入 nn 行詢問,每行輸入四個數字 \mathrmopt、ll、rr、cc,以空格隔開。

若 \mathrm = 0opt=0,表示將位於 [l, r][l,r] 的之間的數字都加 cc。

若 \mathrm = 1opt=1,表示詢問 [l, r][l,r] 中,小於 c^2c2 的數字的個數。

輸出格式

對於每次詢問,輸出一行乙個數字表示答案。

樣例樣例輸入

4

1 2 2 3

0 1 3 1

1 1 3 2

1 1 4 1

1 2 3 2

樣例輸出

3

02

資料範圍與提示

對於 100\%100% 的資料,1 \leq n \leq 50000, -2^ \leq \mathrm1≤n≤50000,−231≤others、\mathrm \leq 2^-1ans≤231−1。

個人思路:二分查詢區間裡面的有多少個符合情況的,時間複雜度差不多是n√nlog√n

#include#include

#include

#include

#include

using

namespace

std;

const

int maxn=50000+5

;int

a[maxn];

intbl[maxn];

int atag[maxn];//

儲存每個塊中所有的元素都要進行的操作

intn;

int block;//

塊的大小

vectorv[maxn];//

儲存每個塊裡面的元素

void reset(int

x)void add(int l,int r,int

c)

for(int i=bl[l]+1;i<=bl[r]-1;i++)//

中間的塊

atag[i]+=c;

}void query(int l,int r,int

c)

if(bl[l]!=bl[r])

}for(int i=bl[l]+1;i<=bl[r]-1;i++)

cout

}int

main()

for(int i=1;i<=bl[n];i++) sort(v[i].begin(),v[i].end());

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

}

(分塊)LOJ 6278 數列分塊入門 2

傳送門 loj 6278 數列分塊入門2 題意 給出乙個長為n的數列,以及n個操作,操作涉及區間加法,詢問區間內小於某個值x的元素個數。為了確保更快地找到區間內小於某個值x的元素個數,對序列進行排序,使得塊內元素有序。每次操作完畢,只需對殘缺塊進行重排。因為對殘缺塊整體加,可能會破壞完整塊的有序性 ...

LOJ 6278 數列分塊入門 2

題意 給出乙個長為 n 的數列,以及 n個操作,操作涉及區間加法,詢問區間內小於某個值 x的元素個數。思路 這裡有兩種操作,一種是區間加法,這在上一部落格已經介紹過了,不會的戳這裡,還有一種是區間查詢,因為每次查詢的數字都是不一樣的,所以要想時間最優化,必須要排序,因為排序後的查詢操作可以達到log...

loj 6278 數列分塊入門 2

題目 區間修改,詢問區間小於c的個數。分塊排序,用vector。至於那個塊的大小,好像要用到均值不等式 我不太會。就開始乙個個試,發現siz sqrt n 4時最快!明天去學一下算分塊複雜度的方法。include include include include include using names...