const int N = 5005;
int t;
struct node
{
ll idx, w;
}q[N];
vector<int> v[N];
int main()
{
//freopen("in.txt", "r", stdin);
int n, m, k;
cin >> n >> m >> k;
//f(i, 1, n)f(j, 1, m)mp[i][j] = i * j / gcd(i, j);
//单调队列k长度区间最值
f(i, 1, n)//水平方向求一遍单调队列
{
int tail = 0, head = 0;
f(j, 1, m)
{
ll lcm = (ll)i*j / gcd(i, j);
while (head<tail &&lcm > q[tail-1].w)//维护递减序列
tail--;//把比当前小,而且老的信息删除
q[tail++] = { j,lcm };
while (head<tail&& j - q[head].idx + 1 > k)head++;
//删去过期信息
if (j >= k)v[i].emplace_back(q[head].w);
}
}
ll ans = 0;
f(i, 0,(int) v[1].size()-1)//竖直方向跑一遍
{
int tail = 0, head = 0;
f(j, 1, n)
{
while (head<tail && v[j][i]> q[tail-1].w)//维护递减序列
tail--;//把比当前小,而且老的信息删除
q[tail++] = { j,v[j][i] };
while (head<tail && j - q[head].idx + 1 > k)head++;
//删去过期信息
if (j >= k)ans += q[head].w;
}
}
cout << ans << endl;
return 0;
}
2020暑期第二场 Fake Maxpooling(单调队列)
最新推荐文章于 2021-05-27 04:39:33 发布