【POJ 1195】 Mobile phones (树状数组)
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 16761 | Accepted: 7713 |
Description
Input
Output
Sample Input
0 4 1 1 2 3 2 0 0 2 2 1 1 1 2 1 1 2 -1 2 1 1 2 3 3
Sample Output
3 4
Source
二维树状数组 一前光写过一维的 一开始写的是第二维树状数组 第一维暴力。。。跑了四千多。。
后来查了查第一维跟第二维一样 累加Lowbite即可 查询的时候用大矩阵减去上面横向矩阵和左面纵向 这样多减了左上角的小矩阵 再加上即可 速度快了好多
兴起封了个类玩。。
代码如下:
#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> using namespace std; class Trie { public: Trie() { memset(tr,0,sizeof(tr)); } void run(int t) { int a,b,c,d; if(!t) { scanf("%d",&a); n = a; } else if(t == 1) { scanf("%d %d %d",&a,&b,&c); Add(a+1,b+1,c); } else { scanf("%d %d %d %d",&a,&b,&c,&d); printf("%d\n",Sum(c+1,d+1)+Sum(a,b)-Sum(a,d+1)-Sum(c+1,b)); } } private: int tr[1033][1033],n; int Lowbite(int x) { return x&(-x); } void Add(int x,int y,int data) { int i,j; for(i = x; i <= n; i += Lowbite(i)) for(j = y; j <= n; j += Lowbite(j)) tr[i][j] += data; } int Sum(int x,int y) { int ans = 0; int i,j; for(i = x; i > 0; i -= Lowbite(i)) for(j = y; j > 0; j -= Lowbite(j)) ans += tr[i][j]; return ans; } }; int main() { int t; Trie *tr = new Trie(); while(~scanf("%d",&t) && t != 3) { tr->run(t); } return 0; }
//原 #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> using namespace std; int tr[1033][1033],n; int Lowbite(int x) { return x&(-x); } void Add(int x,int y,int data) { int i,j; for(i = x; i <= n; i += Lowbite(i)) for(j = y; j <= n; j += Lowbite(j)) tr[i][j] += data; } int Sum(int x,int y) { int ans = 0; int i,j; for(i = x; i > 0; i -= Lowbite(i)) for(j = y; j > 0; j -= Lowbite(j)) ans += tr[i][j]; return ans; } int main() { int t,a,b,c,d; memset(tr,0,sizeof(tr)); while(~scanf("%d",&t) && t != 3) { if(!t) { scanf("%d",&a); n = a; } else if(t == 1) { scanf("%d %d %d",&a,&b,&c); Add(a+1,b+1,c); } else { scanf("%d %d %d %d",&a,&b,&c,&d); printf("%d\n",Sum(c+1,d+1)+Sum(a,b)-Sum(a,d+1)-Sum(c+1,b)); } } return 0; }