bzoj4499 線性函式 線段樹

2022-05-20 09:55:33 字數 1428 閱讀 9811

題目描述

小c最近在學習線性函式,線性函式可以表示為:f(x) = kx + b。現在小c面前有n個線性函式fi(x)=kix+bi ,他對這n個線性函式執行m次操作,每次可以:

1.m i k b 代表把第i個線性函式改為:fi(x)=kx+b 。

2.q l r x 返回fr(fr-1(...fl(x)))  mod  10^9+7 。

輸入第一行兩個整數n, m (1 <= n, m <= 200,000)。

接下來n行,每行兩個整數ki, bi。

接下來m行,每行的格式為m i k b或者q l r x。

輸出對於每個q操作,輸出一行答案。

樣例輸入

5 54 2

3 65 7

2 67 5

q 1 5 1

q 3 3 2

m 3 10 6

q 1 4 3

q 3 4 4

樣例輸出

1825

17978

98題解

線段樹由於所有函式都是一次函式,因此它們復合形成的函式也一定是一次函式。

於是我們可以使用線段樹來維護每個區間從右到左復合所得的一次函式的$k$和$b$。

具體方法:設左邊是$y=k'x+b'$,右邊是$y=k''x+b''$,那麼復合得到的函式為$y=k''(k'x+b')+b''=k'k''x+k''b'+b''$,所以新的$k$為$k'k''$,$b$為$k''b'+b''$。

時間複雜度$o(m\log n)$。

#include #define n 200010

#define mod 1000000007

#define lson l , mid , x << 1

#define rson mid + 1 , r , x << 1 | 1

typedef long long ll;

struct data

}a[n << 2] , t;

char str[10];

inline void pushup(int x)

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

int mid = (l + r) >> 1;

build(lson) , build(rson);

pushup(x);

}void update(int p , int l , int r , int x)

int mid = (l + r) >> 1;

if(p <= mid) update(p , lson);

else update(p , rson);

pushup(x);

}data query(int b , int e , int l , int r , int x)

int main()

return 0;

}

BZOJ4499 線性函式 線段樹

題目大意 小c最近在學習線性函式,線性函式可以表示為 f x kx b。現在小c面前有n個線性函式fi x kix bi 他對這n個線性函式執行m次操作,每次可以 1.m i k b 代表把第i個線性函式改為 fi x kx b 2.q l r x 返回fr fr 1 fl x mod 10 9 7...

bzoj 4499 線性函式 線段樹

題目鏈結 想說的話 沒什麼想說的 題解 我們都知道 f2 f1 x k2 k1 x b1 b2 k1 k2 x k2 b1 b1 然後用線段樹去維護連續的一段最終的f x 是什麼 查詢修改就都很簡單了.include define mod 1000000007 define maxn 200020 ...

bzoj4499 線性函式 線段樹 矩陣乘法

小c最近在學習線性函式,線性函式可以表示為 f x kx b。現在小c面前有n個線性函式fi x kix bi 他對這n個線性函式執行m次操作,每次可以 1.m i k b 代表把第i個線性函式改為 fi x kx b 2.q l r x 返回fr fr 1 fl x mod 10 9 7 1 n,...