标签:
题意:有一个n*m的矩形,一辆车从左上角出发,沿一条路径走,路径是由矩形上每个单元格的边构成的,最后回到左上角,求车子在每个格子转过圈数的平方和。
思路:假设需要记录每个格子转的顺时针的圈数(为负表示转的逆时针),可以考虑车子每次移动对各个格子的贡献:
对于询问,就是求每个点最终的值。这就是一个“区间修改,单点求值”的问题,用二维树状数组即可解决。
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; } |
[LA7139 Rotation(2014 shanghai onsite)]二维树状数组
标签:
原文地址:http://www.cnblogs.com/jklongint/p/4782128.html