有n個數,給定乙個k,求所有長度大於等於k的區間中前k大數的總和。這樣就比較簡單相信大家都會,所以此題要求當k=1~n的總和,即求∑n
k=1∑
n−k+
1i=1
∑nj=
i+k−
1 區間前k大和
input
輸入五個數n,a1,a,b,c。a1表示第乙個數,a,b,c用來生成其餘n-1個數。a(i)=(a(i-1)*a+b)mod c。1<=n<=1,000,000,0<=a1,a,b,c<=1,000,000,000output
乙個數表示答案,最後答案對1,000,000,007取模。input示例
3 3 1 1 10output示例
63樣例解釋:
三個數為3,4,5
k=1:[1,1]=3,[1,2]=[2,2]=4,[1,3]=[2,3]=[3,3]=5(表示各個區間在k=1時的答案)
k=2:[1,2]=7,[2,3]=[1,3]=9
k=3:[1,3]=12
題意:求出所有區間前1大,前2大,前3大...前n大的數的和,當然前提是某個區間有足夠的數。
思路:考慮[l,r]區間的前1大~前r-l+1大的數之和為ans1,轉移到區間[l,r+1],
它的ans2就是ans2=ans1+(x+1)*a[r+1]+y,
其中x是[l,r]小於等於a[r+1]的數量,y是[l,r]大於a[r+1]的數的和,畫圖模擬下就知道了。
令dp[i]為所有右界為i的區間的ans,那麼對於[1,i-1]中小於等於a[i]的數a[j],顯然貢獻了j次;
對於[1,i-1]中大於a[i]的數a[k],貢獻了a[k]*k次,最後加上a[i]自己貢獻了一次。
這些值離散化後用bit維護即可。
# include using namespace std;
typedef long long ll;
const int maxn = 1e6+3;
const ll mod = 1e9+7;
ll a[maxn+3], b[maxn+3], s[2][maxn+3], dp[maxn];
void update(int pos, ll val, int id)
}ll cal(int pos, int id)
return res;
}int main()
for(int i=1; i<=n; ++i)
printf("%lld\n",ans);
return 0;
}
51nod 1712 區間求和
解法 這個題首先考慮乙個簡單情況 對於區間 x,y 權值為多少。容易寫出公式 f x y s y s x 1 sum y sum x 1 x 1 sum x 1 y x 1 其中s x 表示 從第乙個元素到第x個元素的 所有有序二元組的和 題目中定義的 sum表示字首和 這裡要求的是所有a x a ...
51nod 1690 區間求和2
給出乙個長度為n的陣列a。區間 l,r 的值為 r li 0a l i a r i 求所有長度為質數的區間的值的總和。很容易想到,列舉乙個數對,然後統計他的答案 比如說,我們列舉了乙個數對 i j i,j 那麼他的答案的貢獻會有兩種情況 1.i j n 1 i j n 1這個的話,能包含他的區間長度...
51nod 1690 區間求和2
一開始考慮的是對於每個a ia i ai 有哪些a ja j aj 與它相乘,但是這樣做不了。正解是考慮每對 ai aj a i,a j ai a j 的貢獻,然後用fft優化。首先直接把長度為2 22的給算了,然後剩下的都是奇質數長度。預處理s is i si 表示1 11 i ii有多少個奇質數...