結果
問題 | No.2170 Left Addition Machine |
ユーザー |
👑 ![]() |
提出日時 | 2022-11-28 17:01:56 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 2,330 bytes |
コンパイル時間 | 424 ms |
コンパイル使用メモリ | 82,320 KB |
実行使用メモリ | 303,900 KB |
最終ジャッジ日時 | 2024-11-18 06:01:52 |
合計ジャッジ時間 | 43,607 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 62 TLE * 7 |
ソースコード
"""Left Addition Machine 想定TLE解 2間に、A[i-1] >= A[i] となるi-1,iが存在する場合だけ線形"""import sysfrom sys import stdindef rangesum(arr,l,r): #[l:r] (0-indexed) の和を取る arrはあらかじめ累積和しておくことif l == 0:return arr[r]else:return arr[r] - arr[l-1]mod = 998244353#入力を受け取るN,Q = map(int,stdin.readline().split())A = list(map(int,stdin.readline().split()))LR = []for i in range(Q):L,R = map(int,stdin.readline().split())LR.append( (L,R) )#制約チェックassert 1 <= N <= 2*(10**5)assert 1 <= Q <= 2*(10**5)assert len(A) == Nassert len(LR) == Qfor i in range(N):assert 0 <= A[i] < modfor i in range(Q):L,R = LR[i]assert 1 <= L <= R <= N#A[0:r) までの場合を計算fst = [] #fst[i] = A[0:r) までを入れた場合の結果fnew = [0] * N #A[i-1] >= A[i] ならば fnew[i] = 1とする。for i in range(N):if i == 0 or A[i-1] >= A[i]:fst.append(A[i])fnew[i] = 1pw = 1else:fst.append( (fst[-1] + pw * A[i]) % mod )pw *= 2pw %= mod#fnewの累積和を取っておくfor i in range(N-1):fnew[i+1] += fnew[i]powtwo = [1] #2^i を前計算invtwo = [1] #1/2^i を前計算half = pow(2,mod-2,mod) #1/2 (mod 998244353)for i in range(N):powtwo.append(powtwo[-1] * 2 % mod)invtwo.append(invtwo[-1] * half % mod)CS = [A[i] * powtwo[i] % mod for i in range(N)] #解説の配列Cの累積和for i in range(N-1): #累積和を取るCS[i+1] += CS[i]ANS = []for loop in range(Q): #クエリを処理l,r = LR[loop]l -= 1 #0-indexedにするr -= 1if fnew[l] != fnew[r]: #間に、A[i-1] >= A[i] となるi-1,iが存在する#ANS.append( fst[r] % mod )"""変更箇所はこの辺。線形になっている。"""ans = 0for i in range(r,l-1,-1):if A[i-1] >= A[i]:ans += A[i]ans %= modbreakelse:ans *= 2ans += A[i]ans %= modANS.append(ans)else:ANS.append( (A[l] + rangesum(CS,l+1,r) * invtwo[l+1]) % mod )print ("\n".join(map(str,ANS)))