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

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

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

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

  123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
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_JUDGEfreopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGEint 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;
}

转载于:https://www.cnblogs.com/jklongint/p/4782128.html

[LA7139 Rotation(2014 shanghai onsite)]二维树状数组相关推荐

  1. 二维树状数组 ----2021广东省赛 ----- K - Kera‘s line segment[区间转二维平面+树状数组维护前缀最小最大值]

    题目链接 题目大意: 就是一个一维的数轴上面有一堆线段用一个三元组(l,r,val)(l,r,val)(l,r,val)表示. 现在我们有两个操作: 就是往数轴上面添加线段 询问[L,R][L,R][ ...

  2. szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】

    树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...

  3. 【二维树状数组】See you~

    https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F [题意] 给定一个矩阵,每个格子的初始值为1.现在可以对矩阵有四种操作: A ...

  4. POJ_1195 Mobile phones 【二维树状数组】

    题目链接:http://poj.org/problem?id=1195 纯纯的二维树状数组,不解释,仅仅须要注意一点,由于题目中的数组从0開始计算,所以维护的时候须要加1.由于树状数组的下标是不能为1 ...

  5. 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...

  6. 二维树状数组 BZOJ 1452 [JSOI2009]Count

    题目链接 裸二维树状数组 #include <bits/stdc++.h>const int N = 305; struct BIT_2D {int c[105][N][N], n, m; ...

  7. HDU-4456 Crowd 二维树状数组+坐标转换

    题意:给定一个N*N的网格,现在M组操作,一种操作时改变网格上的某个单点的权值,另外一种操作是求到一点曼哈顿距离为小于等于k的所有的权值和,初始化网格所有点的权值为0. 解法:这题如果没有那些特定的条 ...

  8. hdu 1892二维树状数组

    这题我知道是用树状数组,可是好久没打树状数组了,就想用普通方法水过去~~结果--结果--水了好多方法都水不过,出题人真狠呐--我的水方法是对于每一次查询,初始化ans=(x2-x1+1)*(y2-y1 ...

  9. poj 1195(二维树状数组)

    解题思路:这是一道很裸的二维树状数组 AC: #include<stdio.h> #include<string.h> #define N 1100 int c[N][N],n ...

最新文章

  1. 图形文件元数据管理工具exiv2
  2. 阎王爷让我给他做个生死簿后台管理系统
  3. KubeEdge vs K3S:Kubernetes在边缘计算场景的探索
  4. IO:Reactor设计模式
  5. 【数据竞赛】Kaggle GM秘技:树模型初始化技巧
  6. flex 解析json文件_使用 Python 处理 JSON 格式的数据 | Linux 中国
  7. 42 CO配置-控制-产品成本控制-成本对象控制-实际成本核算/物料分类帐-激活实际成本核算
  8. jquery 分片上传php,jquery 大文件分片上传插件 fcup.js
  9. 30岁的我们,生活数据有了哪些改变
  10. 【深入浅出通信原理-学习笔记】信源编码
  11. 【iOS】快捷指令下载动漫屋漫画
  12. 【理解】运用数据透视表制作三栏账
  13. 如何去除2345好压的广告弹窗
  14. 从GoogLeNet架构到deep dream模型
  15. Docker原理及常见命令
  16. 一个bat病毒分析(part1)
  17. Tensorflow操作与函数全面解析
  18. php7 libevent扩展,php7下安装event扩展方法
  19. 朋友合作怎么迈过利益这道坎
  20. 计算机主机无反应,详解电脑开机没反应怎么办

热门文章

  1. [已失效]批量删除“QQ说说
  2. 出场顺序很重要下一句_霍建华马思纯虐恋:人生的出场顺序真得很重要
  3. 00后在线自习,实则涉黄?
  4. 如何使用Django和GraphQL创建URL缩短器
  5. 【VMware 15】【Ubuntu18.04】配置网络~
  6. java投屏 dlna 安卓_DLNA投屏,支持IOS和安卓
  7. pta画菱形(C语言实现)
  8. 教你制作手机电子书android应用 无技术要求
  9. 盲注 mysql 密码_Mysql盲注技巧
  10. 如何快速找出两直线交点?