---待更新---北師大-B:外掛使用拒絕


待更新


鏈接:https://www.nowcoder.com/acm/contest/117/B
來源:牛客網

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld

題目描述
ATG5是ATG系列最新作,遊戲故事發生以美國洛杉磯及其周邊地區爲原型的城市Sos Lantos,是現實地區中的洛杉磯和南加州。製作單位拍攝了超過25萬張相關照片,並且研究了人口調查和汽車銷售數據,以建立遊戲中的世界。

ATG系列歷來都是以黑幫生活爲背景的知名動作冒險遊戲。主人公自然與黑道脫不了干係,在ATG5中游戲元素將會得到增強,加入了更加開放自由的世界,以故事驅動,以任務爲準的遊戲玩法和多人模式。故事主題聚焦金錢永不眠的南加利福尼亞。這次作品是有史以來最具活力的和最多元化的開放式世界,作爲玩家可以反覆進入三個角色的生活,玩交織在一起的所有內容。
ATG5這款遊戲質量很高,但是外掛猖獗。。。

最近,三七開發現了一款神奇的外掛,可以讓他在多個賬號之間轉移金錢。
神奇外掛的神奇不止於此,當他把一個賬號的金錢轉移到另一個賬戶時,原來賬戶裏的金錢並不會減少!是不是很神奇?
三七開一共有n個賬號,每一天他都會通過這個神奇外掛把第1個賬號的金錢“轉移”到第2個賬號,再把第2個賬號的金錢“轉移”到第3個賬號,……,再把第n-1個賬號的金錢“轉移”到第n個賬號。

但是三七開忘了一件事情,遊戲中金錢數量是有上限的,每當一個賬號的金錢數大於等於1000000007(=1e9+7)時,這個賬號的金錢數就會對1e9+7取模,即變成金錢數除以1e9+7的餘數。儘管如此,三七開還是很開心地繼續使用着他的神奇外掛,並且沒有花賬號裏的一分金錢。
然而,在三七開使用了k天神奇外掛之後,B星公司(ATG5的發行公司)發現了他的開掛行爲。B星公司對使用外掛行爲非常仁慈,決定不對三七開進行封號處理,而是將三七開的所有賬號的金錢數恢復至他開掛以前的數值。但服務器並沒有關於那麼久遠的數據的存檔,只有現在的金錢數的數據,以及檢測到的開掛天數k。

你能幫助B星公司恢復三七開的賬號數據嗎?

輸入描述:

第一行是一個正整數T(T ≤ 15),表示測試數據的組數,
對於每組測試數據,
第一行包含兩個整數n(2 ≤ n ≤ 1000),k(0 ≤ k ≤ 100000000),表示賬號個數和開掛天數,
第二行包含n個小於1e9+7的非負整數,第i個整數表示當前第i個賬號的金錢數。

輸出描述:

對於每組測試數據,輸出一行,包含n個以空格分隔的非負整數(每個數範圍小於109+7,注意不要有行末空格),第i個整數表示開掛前第i個賬號的金錢數。

示例
輸入

2
3 1
3 2 1
4 2
1 2 1 2

輸出

3 1000000006 1000000006
1 0 1000000005 2

解題思路:
一:
dp數組表示之前未使用外掛之前的每個帳號的金錢數
假設第一個賬號金錢數爲x,其他都爲0;
則得到下圖:表示在第i天第j個帳號的金錢數

i\j 1 2 3 4 5 6 7 n
0 x 0 0 0 0 0 0
1 x x x x x x x
2 x 2x 3x 4x 5x 6x 7x
3 x 3x 6x 10x 15x 21x 28x
4 x 4x 10x 20x 35x 56x 84x
k x k*x [(k+1)*k/2]x [(k+2)*(k+1)*k/6]x [(k+n-2)(k+n-1)*…*k/(n-1)!]x

   由圖可知,第一個帳號的金錢數x不變,而其他的由(本金)和(左邊帳號的值)組成,即dp[ i ][ j ]=dp[ i -1 ][ j ]+dp[ i ][ j - 1 ];觀察當i==k(即第k天)時帳號的金錢,可得出當j==n時,帳號的金錢數爲 Cn1+k1n1x 。這是當第一天第一個帳號金錢數爲x,而其他帳號均爲零的情況,即反映了一個帳號對其後帳號金錢數的影響。

設每個帳號初始值爲init[ i ],即
v[1] 不變
v[2]=init[1]的影響+init[2]
v[3]=init[1]的影響+init[2]的影響+init[3]
v[4]=init[1]的影響+init[2]的影響+init[ 3 ]的影響+init[4]
······
v[n]=init[1]的影響+init[2]的影響+······+init[n-1]的影響+init[n]
公式化即
  v[n]=Cn1+k1n1 * init[1] + Cn2+k1n2 * init[2] + … + C1+k11 *init[n-1] + C0+k10 *init[n]

因爲v[1]=init[1];知道了init[1]的值,可以一步步求解每個帳號的初始值;

二:
還有一點需要注意,即題中給你的並不是每個帳號的實際金錢數,而是對1e9+7取模過的值;
即 v[2] = (C1+k11 *init[1]+init[2])% mod ;因爲init[2] < mod,
所以原式=((C1+k11 *init[1])) % mod +init[2]) % mod ;
分兩種情況:
<1>:((C1+k11 *init[1])) % mod +init[2])< mod ;
init[2] = v[2] -(C1+k11 *init[1])) % mod ;
<2>:((C1+k11 *init[1])) % mod +init[2])>= mod ;
init[2] = v[2] + mod -(C1+k11 *init[1])) % mod ;
因爲這兩種情況只有一個成立,所以兩個方程解出來的一定有一個是合法的解。

三:
接下來是組合數取模,需要用到乘法逆元,對於此題可以用 費馬小定理 來把除法轉化爲乘法

Cn1+k1n1 %mod =(k1+n1)(k1+n2)(k1+n(n1))(n1)! % mod

= (k1+n1)(k1+n2)(k1+n(n1))(n1)! * [(n1)!](mod1) % mod

=[(k1+n1)(k1+n2)(k1+n(n1))] *[(n1)!](mod2) % mod

=[(k1+n1)(k1+n2)(k1+n(n1))] % mod }*{ [(n1)!](mod2) % mod }

式子的前半部分直接求,後半部分可以用快速冪,因爲值都要使用多次,可以算一遍存在數組裏;即兩個數組:
<1> kn[ i ] 表示 (k-1+i-1) * (k-1+i-2) * … *(k-1+1) % mod ;
<2> nn[ i ] 表示 [(i1)!](mod2) % mod ;

再利用步驟二中的式子求解即可;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章