分塊系列 數列分塊入門7 解題報告

2022-04-29 20:57:09 字數 1681 閱讀 9423

區間乘法,區間加法,單點詢問。

寫過線段樹模板2的童鞋應該很清楚了吧qaq

由於*與markdown衝突,所以用×代替o(* ̄︶ ̄*)o

我們把乙個數表示為 a[i] × tg2[b[i]] + tg1[b[i]]。tg2表示乘法標記,tg1表示加法標記。

對於不完整的塊,直接 a[i] = a[i] × tg2[b[i]] + tg1[b[i]] 將這個塊的所有元素都還原,也就是將該塊的標記下傳。

對於完整的塊

​ 乘法:( a[i] × tg2[b[i]] + tg1[b[i]] ) × c = a[i] × (tg2[b[i]] × c) + (tg1[b[i]] × c) 也就是說,將tg1、tg2都乘c就可以了

​ 加法:( a[i] × tg2[b[i]] + tg1[b[i]] ) + c = a[i] × tg2[b[i]] + (tg1[b[i]] + c) 也就是將tg1加上c

然後就很清楚了ヾ(o・ω・)ノ

#includeusing namespace std;

#define maxn 100005

#define mod(x) (1ll * x) % 10007

int n, d;

int a[maxn], b[maxn], tg1[500], tg2[500];

inline void push( int wh )

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

push(b[l]);

for ( int i = l; b[i] == b[l]; ++i ) a[i] = mod( a[i] + c );

push(b[r]);

for ( int i = r; b[i] == b[r]; --i ) a[i] = mod( a[i] + c );

for ( int i = b[l] + 1; i <= b[r] - 1; ++i ) tg1[i] = mod( tg1[i] + c );

}void mul( int l, int r, int c )

push(b[l]);

for ( int i = l; b[i] == b[l]; ++i ) a[i] = mod( a[i] * c );

push(b[r]);

for ( int i = r; b[i] == b[r]; --i ) a[i] = mod( a[i] * c );

for ( int i = b[l] + 1; i <= b[r] - 1; ++i ) tg1[i] = mod( tg1[i] * c ), tg2[i] = mod( tg2[i] * c );

}int main()

for ( int i = 1; i <= b[n]; ++i ) tg1[i] = 0, tg2[i] = 1;

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

return 0;

}

有多種操作時可以借助代數來分析~(^ω^)

數列分塊入門1

數列分塊入門2

數列分塊入門3

數列分塊入門4

數列分塊入門5

數列分塊入門6

數列分塊入門7

<-

數列分塊入門8

數列分塊入門9

蒲公英公主的朋友

分塊系列 數列分塊入門6 解題報告

單點插入,單點詢問。分塊的小技巧可多啦 o o哈哈 用乙個vector來記錄每個塊的元素。vector提供了強大的insert函式,插入某個元素只要寫一點點就可以啦o o,就是乙個乙個列舉塊,直到找到插入位置屬於哪個塊,然後insert一下就ok。不過,如果插入元素集中於乙個塊的話就尷尬了qaq複雜...

分塊系列 數列分塊入門1 解題報告

區間加法,單點求值。數列分塊是個好東西。我這裡詳細介紹一下分塊演算法,便於初學者的理解 我這個蒟蒻原來也是看不懂分塊 先把陣列分成幾個塊塊,然後就可以對它們整體操作啦。也就是說,把乙個長度為的陣列,拆分成乙個個長度為sqrt n 小塊 當然,最後一塊可能不完整,但是不用管 記錄每個數所屬的塊 也就是...

分塊3 6279 數列分塊入門 3

題目描述 給出乙個長為 nn 的數列,以及 nn 個操作,操作涉及區間加法,詢問區間內小於某個值 xx 的前驅 比其小的最大元素 輸入格式 第一行輸入乙個數字 nn。第二行輸入 nn 個數字,第 ii 個數字為 a iai 以空格隔開。接下來輸入 nn 行詢問,每行輸入四個數字 mathrmopt ...