題目描述
給出乙個長為 nnn 的數列,以及 nnn 個操作,操作涉及區間詢問等於乙個數 ccc 的元素,並將這個區間的所有元素改為 ccc。
輸入格式
第一行輸入乙個數字 nnn。
第二行輸入 nnn 個數字,第 i 個數字為 aia_iai,以空格隔開。
接下來輸入 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,−231≤others、ans≤231−1 \mathrm \leq 2^-1 ans≤231−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的元素個數,對序列進行排序,使得塊內元素有序。每次操作完畢,只需對殘缺塊進行重排。因為對殘缺塊整體加,可能會破壞完整塊的有序性 ...