本文主要是介绍F - Rook on Grid 矩阵 侧面视角 树状数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
两种走法
先下再右 吃到的就是L[i]-1个
先右再下 就吃剩的哈哈 每个L[i]挡住的阴影部分 才是有效的吃到部分
关于阴影 🔥可以想象从矩阵右侧有光线照进来。然后被障碍物挡住的那些空格。
处理方式可以按照列扫过去。一边用树状数组维护那些有阴影的行
实现的主要部分就是怎么去维护那些阴影。
小tip:>=r[i]都当做第一列开始就有阴影
题目
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll __int128_t
#define ar array<int, 2>
#define arr array<int, 3>
int n, m, k, inf = 1LL << 61, mod = 998244353;// 1e9+7;
const int N = 5e5 + 50;
int tr[N + 1];
void add(int x, int v) {while (x <= N) {//这个N-1变量是开放的。。是个隐患。。tr[x] += v, x += x & (-x);}
}
int query(int x) {int s = 0;while (x) {s += tr[x], x -= x & (-x);}return s;
}
void solve() {cin >> n >> m >> k;vector<int>l(n + 1, m + 1), r(m + 1, n + 1);//这边我们统计非法的第一个位置for (int i = 1; i <= k; ++i) {int x, y;cin >> x >> y;l[x] = min(l[x], y);r[y] = min(r[y], x);}int ans = 0;vector<int>mp[m + 2];// 他有可能是m+1 。所以这里要开大点//计算 先下再右for (int i = 1; i < r[1]; ++i) { ans += l[i] - 1;mp[l[i]].push_back(i);}for (int i = r[1]; i <= n; ++i)//>=r[i]都当做第一列开始就有阴影mp[1].push_back(i);//先右再下for (int i = 1; i < l[1]; ++i) {ans += query(r[i] - 1);for (int j : mp[i])add(j, 1);}cout << ans;
};// 这题看似简单。。但是实际上是一类题目的典型处理方式。。signed main() {ios::sync_with_stdio(false);cin.tie(0);cout << fixed << setprecision(15);
#ifdef DEBUGfreopen("../1.in", "r", stdin);
#endif//init_f();//init();//expr();// int T; cin >> T; while(T--)solve();return 0;
}
这篇关于F - Rook on Grid 矩阵 侧面视角 树状数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!