衝刺NOIP2017模擬賽R2
|
序列 |
棋盤 |
貨車 |
源文件名 |
sequence |
chess |
truck |
讀入文件 |
sequence.in |
chess.in |
truck.in |
輸出文件 |
sequence.out |
chess.out |
truck.out |
時間限制 |
1s |
3s |
1s |
空間限制 |
16MB |
256MB |
256MB |
最終評測時不開啓任何優化開關
序列
經歷了上週的慘痛教訓,出題人宋伊雪終於意識到了一道送分題的必要性。那麼這就是你們看到這道題的原因了!
長話短說,宋伊雪會教你一個生成隨機序列的方法,你的目標,是求出這個生成序列的權值最大的連續子串的權值。
輸入包含9個正整數A,B,C,D,E,F,A0,B0,n。
在生成好序列之後,對於每個n,如果bn % 2 == 0,那麼將an改變爲它的相反數。
[輸入格式]
僅一行9個正整數A,B,C,D,E,F,A0,B0,n。
每個數的含義參考題面,n代表你需要生成的序列長度
[輸出格式]
僅一行輸出權值最大的連續子串的權值。
簡單地說,連續子串就是連着的一段數字的意思,可以爲空。
注意,答案不需要考慮
[樣例輸入 1]
1 2 3 2 3 5 23 13 5
[樣例輸出 1]
15382354
[數據範圍]
對於20%的數據,滿足1 <= n <= 10
另有40%的數據,滿足1 <= n <= 1000
另有20%的數據,滿足1 <= n <= 1000000
對於100%的數據,滿足1 <= n <= 10000000,A,B,C,D,E,F,A0,B0,小於2^31
雖然是道簡單的前綴和,只要在計算前綴和的時候順便更新最小的前綴和,把當前前綴和與這個最小前綴和相減,就可以得到最大的連續子序列。
然而第一次打的時候卻意外爆了兩個點。
請教釗爺學長後,,
才知道是自己調用了一個傳遞六個變量的函數,時間複雜度的常數 * 6。
再加上取模操作的運算常數不是1的,於是超了時限。
這裏有必要說下,
合理取模。
此題的方程在相加的部分是不會超出 long long 範圍的
所以沒必要對每步運算都取模
只要相乘操作後取模就行了
科學取模。
順帶一提,取模運算符的優先級是與乘除一檔的。。
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
const LL mo1 = 23333333;
const LL mo2 = 66666666;
LL A,B,C,D,E,F,A0,B0,N;
LL tot,minn,p,q,ans;
/*nline LL js(LL a,LL b,LL c,LL x,LL mo){
return (a * x % mo * x % mo + b * x % mo + c) %mo;
}*/
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
cin >> A >> B >> C >> D >> E >> F >> A0 >> B0 >> N;
p = A0; q = B0;
minn = 0; tot = 0; ans = 0;
for(int i = 1; i <= N; i++){
p = (A * p % mo1 * p % mo1 + B * p % mo1 + C) % mo1;
q = (D * q % mo2 * q % mo2 + E * q % mo2 + F) % mo2;
if(q % 2 == 0) p = -p;
tot += p;
minn = min(tot,minn);
ans = max(ans,tot - minn);
if(p < 0) p = -p;
}
cout << ans;
return 0;
}