區間乘法,區間加法,單點詢問。
寫過線段樹模板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 ...