传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3939
【题解】
f[i][j] = s[i-1][j-1] - sum[a[i][j]]
用cdq分治来处理横坐标,先处理上面的dp值,再讨论上面部分对下面的贡献,然后分治处理下面的dp值即可。
如果加了快读好像排bzoj rk1?
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 7e5 + 10, N = 750 + 10; const int mod = 1e9+7; # define RG register # define ST static int n, m, K; int a[N][N], t[M], f[N][N]; inline void solve(int l, int r) { if(l == r) return ; int mid = l+r>>1, sum = 0; solve(l, mid); for (int j=1; j<=m; ++j) { for (int i=mid+1; i<=r; ++i) { f[i][j] += (sum - t[a[i][j]] + mod) % mod; if(f[i][j] >= mod) f[i][j] -= mod; } for (int i=l; i<=mid; ++i) { sum = sum + f[i][j]; if(sum >= mod) sum -= mod; t[a[i][j]] = t[a[i][j]] + f[i][j]; if(t[a[i][j]] >= mod) t[a[i][j]] -= mod; } } for (int j=1; j<=m; ++j) for (int i=l; i<=mid; ++i) t[a[i][j]] = 0; solve(mid+1, r); } int main() { cin >> n >> m >> K; for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) scanf("%d", &a[i][j]); f[1][1] = 1; solve(1, n); cout << f[n][m]; return 0; }
时间: 2024-10-11 17:27:57