Lawn of the Dead
Lawn of the Dead
題意:
有一個(gè)N * M的方格,我們從(1,1)出發(fā),只能向右走或者向下走,存在一些障礙,問有多少格子是我們所能到達(dá)的
2<=n,m,k<=1e5
題解:
所有的點(diǎn)減去不能到達(dá)的點(diǎn)的個(gè)數(shù),就是可以到達(dá)的點(diǎn)的個(gè)數(shù)
有障礙的地方不能達(dá)到,而我們只能向右向下走,當(dāng)某個(gè)點(diǎn)的左邊和上邊都是不可達(dá)時(shí),該點(diǎn)就不可達(dá),并會(huì)對(duì)自己的右邊的點(diǎn)和下方的點(diǎn)造成影響
n,m,k<=1e5,空間很大但是地雷數(shù)目有限,我們可以從上往下逐行對(duì)每一行的地雷排序后處理,對(duì)于每個(gè)地雷,找到從自己的右上角點(diǎn)(x-1,y+1)開始從左往右的連續(xù)不可達(dá)區(qū)間的范圍,那么x這行的這個(gè)范圍也不可達(dá),我們可以用線段樹來實(shí)現(xiàn)區(qū)間的查詢與維護(hù)。處理每一行,累加后用總點(diǎn)數(shù)減去即可
官方代碼中,將可以到達(dá)的區(qū)域賦值1,每次找第x-1行區(qū)間內(nèi)最最左側(cè)的1,然后將第x行這段區(qū)間賦值為1,剩下0即為不可到達(dá)區(qū)域
代碼:
md調(diào)了半天還是不對(duì)
2021/7/30 0:41
問題解決,現(xiàn)在代碼對(duì)了,睡覺
官方代碼:
#include<bits/stdc++.h> using namespace std; #define ls (x<<1) #define rs (x<<1|1) const int N = 1e5 + 5; const int inf = 0x3f3f3f3f; vector<int>e[N]; int tr[2][N << 2], lz[2][N << 2];void push_down(int f, int x, int l, int r, int mid) {if (lz[f][x] == -1)return;tr[f][ls] = lz[f][x] * (mid - l + 1);tr[f][rs] = lz[f][x] * (r - mid);lz[f][ls] = lz[f][rs] = lz[f][x];lz[f][x] = -1; } void update(int f,int x, int l, int r, int L, int R, int v) {if (L <= l && R >= r) {tr[f][x] = (r - l + 1) * v;lz[f][x] = v;return;}int mid = (l + r) >> 1;push_down(f, x, l, r, mid);if (R <= mid)update(f, ls, l, mid, L, R, v);else if (L > mid)update(f, rs, mid + 1, r, L, R, v);else {update(f, ls, l, mid, L, mid, v);update(f, rs, mid + 1, r, mid + 1, R, v);}tr[f][x] = tr[f][ls] + tr[f][rs]; } int query(int f, int x, int l, int r, int L, int R) {if (!tr[f][x])return inf;if (l == r)return l;int mid = l + r >> 1;push_down(f, x, l, r, mid);if (L <= l && R >= r) {if (tr[f][ls] > 0) return query(f, ls, l, mid, L, R);else return query(f, rs, mid + 1, r, L, R);}else {if (R <= mid)return query(f, ls, l, mid, L, R);else if (L > mid)return query(f, rs, mid + 1, r, L, R);else return min(query(f, ls, l, mid, L, mid), query(f, rs, mid + 1, r, mid + 1, R));} } int main() {int T;scanf("%d", &T);while (T--) {int n, m, k;scanf("%d %d %d", &n, &m, &k);for (int i = 1; i <= n; ++i)e[i].clear();for (int i = 1; i <= (m << 2); ++i) {tr[0][i] = tr[1][i] = 0;lz[0][i] = lz[1][i] = -1;}for (int i = 0; i < k; ++i) {int x, y;scanf("%d %d", &x, &y);e[x].push_back(y);}long long ans = 0;update(0, 1, 1, m, 1, 1, 1);for (int x = 1; x <= n; ++x) {int l = 0;sort(e[x].begin(), e[x].end());for (auto& y : e[x]) {if (y - 1 >= l + 1) {int pos = query((x & 1) ^ 1, 1, 1, m, l + 1, y - 1);if (pos != inf)update(x & 1, 1, 1, m, pos, y - 1, 1);}l = y;}if (l + 1 <= m) {int pos = query((x & 1) ^ 1, 1, 1, m, l + 1, m);if (pos != inf)update(x & 1, 1, 1, m, pos, m, 1);}ans += tr[x & 1][1];update((x & 1) ^ 1, 1, 1, m, 1, m, 0);}printf("%lld\n", ans);}return 0; }總結(jié)
以上是生活随笔為你收集整理的Lawn of the Dead的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 漂亮又简单的灯笼做法 怎么做漂亮又简单的
- 下一篇: Acwing 271. 杨老师的照相排列