題目大概是這樣的:
給出乙個長度為n
nn的序列,m
mm次詢問,q
qq為引數,有兩種操作
給區間∀i∈
[l,r
]i\in[l,r]
∀i∈[l,
r]的數字加上qi−
lq^
qi−l
詢問區間[l,
r]
[l,r]
[l,r
]的數字和
n ,m
<=1
05,1
<
q<=1
09
n,m<=10^5,1n,
m<=1
05,1
<
q<=1
09分析:既然題目說q
>
1q>1
q>
1,那麼就可以用等比數列求和公式來計算加了多少了,而且對於所有的操作,q都是一致的,那麼懶標記可以記錄這段區間的要加的等比數列的首項就可以!
下傳標記的時候注意左子樹可以直接加過來,因為他們的首項相同,右子樹就需要補上qmi
d+1−
lq^
qmid+1
−l了。
聽老師yy的一道題,也沒有找到交的地方,自己寫了寫暴力對拍了好多資料都過了,需要注意乘法的時候需要用快速乘,因為逆元還有標記還有次冪陣列乘起來會炸long long。
輸入格式就是:n,m
,q
n,m,q
n,m,
q序列元素
m
mm次操作,id,
l,
rid,l,r
id,l,r
,id為1是修改,2是查詢。
#include
using namespace std;
typedef
long
long ll;
const
int maxn=
1e5+7;
const
int mod=
1e9+7;
ll ci[maxn]
;ll sum[maxn<<2|
1];ll lazy[maxn<<2|
1];ll q;
ll ni;
ll quick
(ll a,ll b)
return res;
}void
pushup
(int k)
ll ksc
(ll x,ll y,ll mod)
void
build
(int l,
int r,
int k)
int mid=
(l+r)
>>1;
build
(l,mid,k<<1)
;build
(mid+
1,r,k<<1|
1);pushup
(k);
}void
pushdown
(int l,
int r,
int k)
}void
updata
(int l,
int r,
int k,
int l,
int r)
pushdown
(l,r,k)
;int mid=
(l+r)
>>1;
if(l<=mid)
updata
(l,mid,k<<
1,l,r);if
(r>mid)
updata
(mid+
1,r,k<<1|
1,l,r)
;pushup
(k);
}ll myfind
(int l,
int r,
int k,
int l,
int r)
intmain()
return0;
}
暴力:
#include
using namespace std;
typedef
long
long ll;
const
int maxn=
1e5+7;
ll a[maxn]
;const
int mod=
1e9+7;
ll ci[maxn]
;int
main()
}return0;
}造資料
/*#includeusing namespace std;
const int maxn=1e5;
const int qq=1e9;
const int mod=1e9+7;
int main()
return 0;
}*/
用等比數列解析偽列level的另乙個作用
我們都知道,level是個偽列,代表當前節點所在的層級 對根節點來說,level返回1 根節點到子節點返回2,以此類推。借助level,我們可以控制對錶的掃瞄次數。第一次掃瞄得出的結果集的level都是1,第二次掃瞄的結果集的level都是2,依此類推。實驗環境 sql create table t...
用等比數列解析偽列level的另乙個作用
我們都知道,level是個偽列,代表當前節點所在的層級 對根節點來說,level返回1 根節點到子節點返回2,以此類推。借助level,我們可以控制對錶的掃瞄次數。第一次掃瞄得出的結果集的level都是1,第二次掃瞄的結果集的level都是2,依此類推。實驗環境 sql create table t...
一種類似等比數列求和問題的解法
有時,會遇到這樣的問題 求 sum n i kx i 其中,k很小,n很大,x可以是數,矩陣,或多項式。通常,有兩種做法 將x放入矩陣中,並依次把 a 1 i 拆開,把係數放入矩陣 其實就是楊輝三角 這個方法比較容易,但時間複雜度為 o k 3 log n 使用遞迴。從 frac n 2 的答案推到...