loj 6284 數列分塊入門 8

2021-08-16 04:23:13 字數 1703 閱讀 2061

題目描述

給出乙個長為 nnn 的數列,以及 nnn 個操作,操作涉及區間詢問等於乙個數 ccc 的元素,並將這個區間的所有元素改為 ccc。

輸入格式

第一行輸入乙個數字 nnn。

第二行輸入 nnn 個數字,第 i 個數字為 aia_ia​i​​,以空格隔開。

接下來輸入 nnn 行詢問,每行輸入三個數字 lll、rrr、ccc,以空格隔開。

表示先查詢位於 [l,r][l,r][l,r] 的數字有多少個是 ccc,再把位於 [l,r][l,r][l,r] 的數字都改為 ccc。

輸出格式

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

樣例樣例輸入

4 1 2 2 4

1 3 1

1 4 4

1 2 2

1 4 2

樣例輸出

1 1

0 2

資料範圍與提示

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

直接非常暴力搞就可以 因為乙個操作必定連線著乙個染色操作 所以假設我需要讓所有塊都暴力重構 那麼我必定需要sqrt(n)個前置操作才可以實現 所以總的複雜度是n*sqrt(n)的

怎麼暴力 就每個區間打乙個懶標記 如果有懶標記並且==c那麼直接統計區間長度 否則就暴力掃一遍

#include

#include

#include

#define n 110000

using namespace std;

inline char gc()

return

*s++;

}inline int

read()

while(ch<='9'&&ch>='0') x=x

*10+ch-'0',ch=gc();

return

x*f;

}int n,nn,a[n],ri[n],lf[n],b[n],len[n];

int lazy[n];bool tag[n];

int main()

for (int i=1;i1)*nn+1,ri[i]=i*nn,len[i]=nn;

lf[nx]=(nx-1)*nn+1;ri[nx]=n;len[nx]=n-(nx-1)*nn;

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

for (int i=l;i<=r;++i) tmp+=(a[i]==c),a[i]=c;printf("%d\n",tmp);continue;

}for (int i=b[l]+1;iif (!tag[i]) if (tag[i]&&lazy[i]==c) tmp+=len[i];lazy[i]=c;tag[i]=1;

}if(tag[b[l]])

for (int i=l;i<=ri[b[l]];++i) tmp+=(a[i]==c),a[i]=c;

if(tag[b[r]])

for (int i=lf[b[r]];i<=r;++i) tmp+=(a[i]==c),a[i]=c;printf("%d\n",tmp);

}return

0;}

6284 數列分塊入門 8

題目描述 給出乙個長為 n的數列,以及 n 個操作,操作涉及區間詢問等於乙個數 c 的元素,並將這個區間的所有元素改為 c。輸入格式 第一行輸入乙個數字 n。第二行輸入 n個數字,第 i 個數字為 ai 以空格隔開。接下來輸入 n行詢問,每行輸入三個數字 l r c,以空格隔開。表示先查詢位於 l,...

LOJ 數列分塊入門 1

link 優雅的暴力,對於乙個數列,他不是乙個元素乙個元素處理,而是分成若干塊,成塊成塊的處理,以此達到降低時間複雜度的目的。首先,我們需要處理劃分的塊的大小 block 一般是根號n 塊的數目 每乙個元素對應第幾塊,然後,每一塊的左端點和右端點。完整的塊 更新 我們用lz i lz i lz i ...

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

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