zoukankan      html  css  js  c++  java
  • [LA7139 Rotation(2014 shanghai onsite)]二维树状数组

    题意:有一个n*m的矩形,一辆车从左上角出发,沿一条路径走,路径是由矩形上每个单元格的边构成的,最后回到左上角,求车子在每个格子转过圈数的平方和。

    思路:假设需要记录每个格子转的顺时针的圈数(为负表示转的逆时针),可以考虑车子每次移动对各个格子的贡献:

    • 车子左移,路径上方所有格子转的圈数+1,路径下方所有格子-1,而上方和下方所有格子都形成大的矩形,于是相当于每次对矩形区域的格子全部执行加减操作。
    • 车子右移,上方-1,下方+1。
    • 车子上移,左边-1,右边+1。
    • 车子下移,左边+1,右边-1。

    对于询问,就是求每个点最终的值。这就是一个“区间修改,单点求值”的问题,用二维树状数组即可解决。

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    #pragma comment(linker, "/STACK:10240000")
    #include <bits/stdc++.h>
    using namespace std;
    
    #define X                   first
    #define Y                   second
    #define pb                  push_back
    #define mp                  make_pair
    #define all(a)              (a).begin(), (a).end()
    #define fillchar(a, x)      memset(a, x, sizeof(a))
    
    typedef long long ll;
    typedef pair<int, int> pii;
    
    #ifndef ONLINE_JUDGE
    namespace Debug {
    void print(){cout<<endl;}template<typename T>
    void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
    void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
    void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
    }
    #endif // ONLINE_JUDGE
    template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
    template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
    /* -------------------------------------------------------------------------------- */
    
    struct TA {
        vector<vector<int> > r;
        int n, m;
        void resize(int n, int m) {
            this->n = n;
            this->m = m;
            r.resize(n + 1);
            for (int i = 1; i <= n; i ++) {
                r[i].clear();
                r[i].resize(m + 1);
            }
        }
        inline int lowbit(const int &x) {
            return x & -x;
        }
        void update(int px, int py, int v) {
            int buf = py;
            while (px <= n) {
                py = buf;
                while (py <= m) {
                    r[px][py] += v;
                    py += lowbit(py);
                }
                px += lowbit(px);
            }
        }
        void update(int px1, int py1, int px2, int py2, int v) {
            update(px1, py1, v);
            update(px1, py2 + 1, -v);
            update(px2 + 1, py1, -v);
            update(px2 + 1, py2 + 1, v);
        }
        int query(int px, int py) {
            int ans = 0, buf = py;
            while (px) {
                py = buf;
                while (py) {
                    ans += r[px][py];
                    py -= lowbit(py);
                }
                px -= lowbit(px);
            }
            return ans;
        }
    };
    TA ta;
    
    ll sqr(int x) {
        return (ll)x * x;
    }
    
    const int dx[4] = {0, 0, 1, -1};
    const int dy[4] = {1, -1, 0, 0};
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
    #endif // ONLINE_JUDGE
        int T, cas = 0, n, m, k, s, x, y, xx, yy, d0, f[128];
        char d[3];
        f['R'] = 0;
        f['L'] = 1;
        f['D'] = 2;
        f['U'] = 3;
        cin >> T;
        while (T --) {
            cin >> n >> m >> k;
            n ++;
            m ++;
            ta.resize(n, m);
            x = y = 1;
            while (k --) {
                scanf("%s%d", &d, &s);
                d0 = f[d[0]];
                xx = x + dx[d0] * s;
                yy = y + dy[d0] * s;
                if (d[0] == 'L') {
                    ta.update(1, yy, x - 1, y - 1, 1);
                    ta.update(x, yy, n - 1, y - 1, -1);
                }
                if (d[0] == 'R') {
                    ta.update(1, y, x - 1, yy - 1, -1);
                    ta.update(x, y, n - 1, yy - 1, 1);
                }
                if (d[0] == 'U') {
                    ta.update(xx, 1, x - 1, y - 1, -1);
                    ta.update(xx, y, x - 1, m - 1, 1);
                }
                if (d[0] == 'D') {
                    ta.update(x, 1, xx - 1, y - 1, 1);
                    ta.update(x, y, xx - 1, m - 1, -1);
                }
                x = xx;
                y = yy;
            }
            ll ans = 0;
            for (int i = 1; i < n; i ++) {
                for (int j = 1; j < m; j ++) {
                    ans += sqr(ta.query(i, j) / 4);
                }
            }
            cout << "Case #" << ++ cas << ": " << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    吴裕雄--天生自然 诗经:离思五首·其四
    吴裕雄--天生自然 诗经:江城子·乙卯正月二十日夜记梦
    CentOS6—启动httpd失败—Certificate has expired
    paper—SCI—Examples of author responses to reviewer comments
    paper—SCI答复审稿人的回信技巧
    mysql android—Installation using AndroPHP
    linux socket c : send data when socket close—SIGPIPE, Broken pipe
    Firefox:曾经打破黑暗的产品
    mysql中datetime到time_t转换
    mysql datetime 时间比较
  • 原文地址:https://www.cnblogs.com/jklongint/p/4782128.html
Copyright © 2011-2022 走看看