對於這種式子\(f(l,r)=(\sum_^a_i)\times w_\) 一般情況下,我們先仿照答案寫出前幾項,看看有沒有規律
定義字首和 \(s_k=\sum_^a_i\) ,把要求出的式子\(\sum_^\sum_^f(l,r)\)展開來寫
\[\begin
=&f(1,1)+f(1,2)+f(1,3)+f(1,4)\dots+f(1,n)+\\
&f(2,2)+f(2,3)+f(2,4)+\dots+f(2,n)+\\
&f(3,3)+f(3,4)+\dots+f(3,n)+\\
&\dots+\\
&f(n,n)\\
=&s_1w_1+s_2w_2+s_3w_3+s_4w_4\dots+s_nw_n+\\
&(s_2-s_1)w_1+(s_3-s_1)w_2+(s_4-s_1)w_3+\dots+(s_n-s_1)w_+\\
&(s_3-s_2)w_1+(s_4-s_2)w_2+\dots+(s_n-s_2)w_+\\
&\dots+\\
&(s_-s_)w_1+(s_-s_)w_2+\\
&(s_n-s_)w_1\\
\end
\]然後,通過觀察發現,可以把每乙個列\(w_i\) 相加的值,合併到一起
建議列成一排這樣約分一眼就看出來了,每次都是前面空出幾項,後面空出幾項
\[\begin
s_nw_1=&(s_1+s_2-s_1+s_3-s_2+\dots+s_-s_+s_-s_)w_1\\
(s_+s_-s_1)w_2=&(s_2+s_3-s_1+s_4-s_2+\dots+s_-s_+s_-s_+s_-s_)w_2\\
(s_n+s_+s_-s_2-s_1)w_3=&\dots\\
&\dots\\
s_nw_n
\end
\]通過觀察式子,我們發現
\(w_i\) 對應\(s_n-0\) 加一項 \(s_n\) 減去\(0\) 項
\(w_2\) 對應\(s_n+s_-s_1\) 加兩項\(s_n+s_\) 減去\(1\) 項
\(w_3\) 對應\(s_n+s_+s_-s_2-s_1\) 加三項\(s_n+s_+s_\) 減去\(2\) 項
而且這些加的,或者減去的,都是一段區間的數字,也可以用字首和來優化
定義字首和\(e_k=\sum^_s_i\) ,改寫原先的式子,即
\(s_nw_1=e_1w_1\)
\((s_n+s_-s_1)w_2=(e_n-e_-e_1)w_2\)
\((s_n+s_+s_-s_2-s_1)w_3=(e_n-e_-e_2)w_3\)
得到通式 \((e_n-e_-e_)w_i\)
然後我們就可以應用兩遍字首和 \(o(n)\) 求出答案了
最終式子\(ans=\sum^_(e_n-e_-e_)w_i\) ,記得每步都取模
有個細節,\(e\) 陣列要用\(long long\) 不然在求字首和的時候會爆掉,因為\(s\) 已經是臨界值了,\(e\) 和 \(s\) 兩個相加會先爆掉再取模
#include using namespace std;
#define endl '\n'
#define io ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef long long ll;
const int n = 3e5 + 5;
const int mod = 1e9 + 7;
int a[n],w[n],s[n],n;
ll e[n];
int main()
牛客國慶集訓派對Day4
a 把b n include include include includeusing namespace std int main d 由於是個完全圖,選擇乙個權值最小的點,其他所有的點向它連線就行了。注意點為1的時候輸出0 include include include includeusing...
2020牛客國慶集訓派對day4 補題
2020牛客國慶集訓派對day4 b 題意 題意 求最長等差序列的長度。dp 攤派了我講不明白,參考下這兩篇部落格吧 捂臉 傳送門1 傳送門2 include include include include include include include using namespace std ty...
牛客國慶集訓派對Day4 G I H
小 bo 有 n 個正整數 a1.an,以及乙個權值序列 w1 wn,現在他定義 現在他想知道 你只需要輸出答案對 109 7 取模後的值 第一行乙個正整數 n 第二行 n 個正整數 a1.an 第三行 n 個正整數 w1.wn 輸出答案對 109 7 取模後的值示例1 複製3 1 1 1 1 1 ...