字首和 蒜頭君班級排隊打水

2021-10-12 08:29:05 字數 1745 閱讀 3012

題目是這樣的:

這道題如果不考慮時間的話很容易解,但最後會超時。

所以這道題的關鍵就在於如何用一層迴圈解決。

解決思路如下:

首先這道題在草稿紙上演算,拿輸入樣例來說,如果要知道某個區間打水的人花費的時間總和,可以先不看特定區間,先算出每個人打水需要的時間,我們把每個人打水需要的時間存到乙個新的陣列裡,命名為b[n]

也就是

a[n] 1 3 5 4 2

b[n] 1 4 9 13 15

於是每個人打水需要的時間就有啦,他問時間和,假如說我們要的區間就是從第1個人到第n個人,也就是每次都是從第乙個人開始的,如果是這種情況,我們則需要b1+b2+…+bn

如果兩次迴圈不超時那分析到這裡就已經沒問題了,關鍵是如何不用雙重迴圈來實現乙個區間的加和呢。我們只能用一重迴圈的話,本來自閉了很久覺得impossible,但想了想沒有什麼是再加乙個陣列或者結合數學列個式子不能解決的了(誤

於是我們還按照那個從1到n取區間走起,我們目的是求和b1+b2+…+bn ,那我們再來加個陣列 c[n] c[i]是b[1]到b[i] 的加和

於是乎是醬紫

a[n] 1 3 5 4 2

b[n] 1 4 9 13 15

c[n] 1 5 14 28 43

也就是字首和的字首和嗯…這個出來了,之後就是想如何實現任意區間,那不就用第三個陣列做個減法的事嘛,其實題目中已經給提示了,取乙個連續區間。因為用一重迴圈所以必須做到給出l,r就能算出結果,那就必須要寫乙個式子! 所以草稿紙上演算一下,不難得出

sum += (c[r]-c[l-1]-b[l-1]*(r-l+1))%1000000007;

於是肯定會想為啥要再取餘一下(在這裡沒考慮過,於是卡了乙個小時)因為本來就是long long int,進行加法會爆掉的的的 所以記得在這裡取餘一下

好啦,上**(注意long longi nt

#include

long

long

int n,q,l,r,i,j;

long

long

int sum=0;

long

long

int a[

100100]=

;long

long

int b[

100100]=

;long

long

int c[

100100]=

;int

main()

scanf

("%d"

,&q)

;for

(j=1

;j<=q;j++

)printf

("%d"

,sum%

1000000007);

return0;

}

差分法 字首和 蒜頭君的數字

大致思路 很明顯,很大的數字,暴力是會超時的。所以比較好的方法是差分法 字首和。第一次接觸,就題說一說自己的理解。可以想象所有的數平鋪在地上,如果要把乙個區間上的數都同時加d,那麼很直觀地,就是一座一座山堆在上面。請發揮想象力!那麼,我只需要把區間的首的sum值 d,尾 1處的sum值 d 同時注意...

蒜頭君面試

題目 問題描述 蒜頭君來蒜廠面試的時候,曾經遇到這樣乙個面試題 給定 n 個整數,求裡面出現次數最多的數,如果有多個重複出現的數,求出值最大的乙個。當時可算是給蒜頭君難住了。現在蒜頭君來考考你。輸入格式 第一行輸入乙個整數n 1 n 100000 接下來一行輸入n個 int 範圍內的整數。輸出格式 ...

蒜頭君下棋

蒜頭君下棋 共一行,兩個整數nn和mm 1 leq n m leq 10001 n,m 1000 代表棋盤一共有 nn 行 mm 列。輸出乙個整數,代表棋盤上最多能放的馬的數量。樣例輸入1複製 2 4樣例輸出1複製 4樣例輸入2複製 3 4樣例輸出2複製 6 1 當棋盤只有一行時,棋盤上全放上棋子即...