洛谷 P8572 [JRKSJ R6] Eltaw 做題記錄

coding_goat_qwq發表於2024-10-17

zhr 隨機跳題跳到的,遂做之。

注意到 \(nk \le 5\times10^5\),考慮根號分治。
\(n\) 很大時,\(k\) 會很小,於是我們記錄每一行的字首和,每一次迴圈 \(k\) 個陣列的字首和取 \(\max\) 即可,時間複雜度 \(O(qk)\)
\(k\) 很大時,\(n\) 會很小,我們暴力預處理區間 \([l,r]\) 的最大值,直接輸出即可,時間複雜度 \(O(n^2k+q)\)
取閥值為 \(\sqrt n\) 的時候,可以在兩邊都達到最小值。

點選檢視程式碼
int n,k,q;
vector<int>a[maxn];
vector<int>pre[maxn];
const int lim=750;
int ans[lim+5][lim+5];
signed main() {
	in3(n,k,q);
	For(i,1,k) {
		a[i].push_back(0);
		pre[i].push_back(0);
		For(j,1,n) {
			int x;
			in1(x);
			a[i].push_back(x);
			pre[i].push_back(x+pre[i][j-1])	;	
		}
	}
	if(k<lim) {
		For(i,1,q) {
			int l,r;
			in2(l,r);
			int ans=-1e18;
			For(j,1,k) 
				ans=max(ans,pre[j][r]-pre[j][l-1]);
			cout<<ans<<'\n';
		}
		return 0;
	}
	For(i,1,n) For(j,1,n) ans[i][j]=-1e18;
	For(i,1,k) {
		For(j,1,n) {
			int tot=0;
			For(p,j,n) {
				tot+=a[i][p];
				ans[j][p]=max(ans[j][p],tot);
			}
		}
	}
	For(i,1,q) {
		int l,r;
		in2(l,r);
		cout<<ans[l][r]<<'\n';
	}
}