zoukankan      html  css  js  c++  java
  • Gym-101470C

    C - UFO

    题意

    给一个 (n imes m) 的矩形,代表对应位置方块的数目,现在进行 (k) 次激光攻击,每次激光攻击会在高度 (h) 处从 (N,S,W,E) 四个方向中的一个向对面发射激光,若命中一个块,则改方块消失,每次激光最多消灭 (r) 个方块。

    攻击结束后,方块会掉落。问最后在 (p imes p) 的矩形内,最多有多少个方块

    image-20210311101215846

    (1 le n*m le 1e6) , (1 le r le 10) , (1le kle 3e5) , (1 le p le min(n,m,10))

    思路

    用线段树模拟即可,每次找区间内第一个大于等于某个值的元素,或者最后一个大于等于某个元素(高度)的值,

    最后做一个二维前缀和

    #include<bits/stdc++.h>
    using namespace std;
    
    #define lo (o << 1)
    #define ro (o << 1 | 1)
    #define mid (l + r >> 1)
    #define what(x) cerr << #x << " is " << x << endl;
    #define getall(x,ed) cerr << #x << ": 	";debug(x,ed);
    template<typename T>
    void debug(T begin, T ed) {
        for (T i = begin;i != ed;i++)cout << *i << '	';cout << '
    ';
    }
    
    
    typedef long long ll;
    
    int n, m, r, k, p;
    vector<vector<int>>mp, RTree, CTree;
    vector<vector<ll>>qzh;
    void build(vector<int>& Tree, int o, int l, int r, int type, int idx) {
        if (l == r) {
            if (type == 0) {
                Tree[o] = mp[idx][l];
            }
            else {
                Tree[o] = mp[l][idx];
            }
            return;
        }
        build(Tree, lo, l, mid, type, idx);build(Tree, ro, mid + 1, r, type, idx);
        Tree[o] = max(Tree[lo], Tree[ro]);
    }
    int query_first(vector<int>& Tree, int L, int R, int tar, int o, int l, int r) {
        if(l == r){
            if(Tree[o] >= tar)return l;
            else return -1;
        }
        if (L <= l and r <= R) {
            if(Tree[o] < tar) return -1;
        }
        int ans = -1;
        if (L <= mid) ans = query_first(Tree, L, R, tar, lo, l, mid);
        if (ans != -1)return ans;
        if (R > mid)ans = query_first(Tree, L, R, tar, ro, mid + 1, r);
        return ans;
    }
    int query_last(vector<int>& Tree, int L, int R, int tar, int o, int l, int r) {
        if (l == r) {
            if (Tree[o] >= tar)return l;
            else return -1;
        }
        if (L <= l and r <= R) {
            if (Tree[o] < tar) return -1;
        }
        int ans = -1;
        if (R > mid)ans = query_last(Tree, L, R, tar, ro, mid + 1, r);
        if (ans != -1)return ans;
        if (L <= mid) ans = query_last(Tree, L, R, tar, lo, l, mid);
        return ans;
    }
    void updtTree(vector<int>& Tree, int pos, int o, int l, int r) {
        if (l == r) {
            Tree[o]--;
            return;
        }
        if (pos <= mid)updtTree(Tree, pos, lo, l, mid);
        else updtTree(Tree, pos, ro, mid + 1, r);
        Tree[o] = max(Tree[lo], Tree[ro]);
    }
    void modify(int r, int c) {
        updtTree(RTree[r], c, 1, 1, m);
        updtTree(CTree[c], r, 1, 1, n);
        mp[r][c]--;
    }
    
    int main() {
    #ifdef ONLINE_JUDGE
        freopen("c.in", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
        scanf("%d%d%d%d%d", &n, &m, &r, &k, &p);
        mp.resize(n + 1, vector<int>(m + 1, 0));
        for (int i = 1;i <= n;i++)for (int j = 1;j <= m;j++)scanf("%d", &mp[i][j]);
        RTree.resize(n + 1, vector<int>((m + 1) << 2, 0));
        CTree.resize(m + 1, vector<int>((n + 1) << 2, 0));
    
        for (int i = 1;i <= n;i++)build(RTree[i], 1, 1, m, 0, i);
        for (int i = 1;i <= m;i++)build(CTree[i], 1, 1, n, 1, i);
    
        //puts("build");
    
        while (k--) {
            char dir[2];int pos, h;
            scanf("%s%d%d", dir, &pos, &h);
            if (*dir == 'N') {
                int L = 1, R = n;
                for (int k = 1;k <= r;k++) {
                    int p = query_first(CTree[pos], L, R, h, 1, 1, n);
                    if (p == -1)break;
                    modify(p, pos);
                    L = p + 1;
                }
            }
            else if (*dir == 'S') {
                int L = 1, R = n;
                for (int k = 1;k <= r;k++) {
                    int p = query_last(CTree[pos], L, R, h, 1, 1, n);
                    if (p == -1)break;
                    modify(p, pos);
                    R = p - 1;
                }
            }
            else if (*dir == 'W') {
                int L = 1, R = m;
                for (int k = 1;k <= r;k++) {
                    int p = query_first(RTree[pos], L, R, h, 1, 1, m);
                    if (p == -1)break;
                    modify(pos, p);
                    L = p + 1;
                }
            }
            else if (*dir == 'E') {
                int L = 1, R = m;
                for (int k = 1;k <= r;k++) {
                    //what(pos);what(h);
                    int p = query_last(RTree[pos], L, R, h, 1, 1, m);
                    if (p == -1)break;
                    modify(pos, p);
                    R = p - 1;
                }
            }
    
        }
        //puts("ok");
        qzh.resize(n + 1, vector<ll>(m + 1, 0));
        // for(int i = 1;i <= n;i++){
        //     for(int j = 1;j <= m;j++){
        //         cout << mp[i][j] << " ";
        //     }cout << '
    ';
        // }
        //getall(mp[1].begin() + 1, mp[1].end());
        ll ans = 0;
        for (int i = 1;i <= n;i++) {
            for (int j = 1;j <= m;j++) {
                qzh[i][j] = mp[i][j] + qzh[i - 1][j] + qzh[i][j - 1] - qzh[i - 1][j - 1];
                if (i >= p and j >= p) {
                    ans = max(ans, qzh[i][j] - qzh[i - p][j] - qzh[i][j - p] + qzh[i - p][j - p]);
                }
            }
        }
        
        printf("%lld
    ", ans);;
    }
    
  • 相关阅读:
    【Java EE 学习 81】【CXF框架】【CXF整合Spring】
    【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】
    【Java EE 学习 80 上】【WebService】
    【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】
    【Java EE 学习 79 上】【mybatis 基本使用方法】
    【Java EE 学习 78 下】【数据采集系统第十天】【数据采集系统完成】
    【Java EE 学习 78 中】【数据采集系统第十天】【Spring远程调用】
    【Java EE 学习 78 上】【数据采集系统第十天】【Service使用Spring缓存模块】
    【Java EE 学习 77 下】【数据采集系统第九天】【使用spring实现答案水平分库】【未解决问题:分库查询问题】
    【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
  • 原文地址:https://www.cnblogs.com/sduwh/p/14516179.html
Copyright © 2011-2022 走看看