本文主要是介绍树状数组模板+poj1195(二维树状数组),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
感谢学长的博客~~http://blog.csdn.net/lin375691011/article/details/21247409
在数组长度为n的树状数组中:
寻找下一个需要添加的数的下标:
int lowbit(int x)
{ return x&(-x);
}
一维树状数组更新是这样的:
void add(int x,int val)
{ for(;x<=n;x+=lowbit(x)) { num[x]+=val; }
}
二维树状数组更新是这样的:
void add(int x,int y,int val)
{ for(int i=x;i<=s;i+=lowbit(i)) { for(int j=y;j<=s;j+=lowbit(j)) { num[i][j]+=val; } }
}
一维树状数组查询是这样的:
int query(int x)
{ int ans=0; for(;x>0;x-=lowbit(x)) { ans+=c[i]; } return ans;
}
二维树状数组查询是这样的
int query(int x,int y)
{ int ans=0; for(int i=x;i>0;i-=lowbit(i)) { for(int j=y;j>0;j-=lowbit(j)) { ans+=num[i][j]; } } return ans;
}
下面看一个纯二维的树状数组模板题
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 18744 | Accepted: 8647 |
Description
Write a program, which receives these reports and answers queries about the current total number of active mobile phones in any rectangle-shaped area.
Input
The values will always be in range, so there is no need to check them. In particular, if A is negative, it can be assumed that it will not reduce the square value below zero. The indexing starts at 0, e.g. for a table of size 4 * 4, we have 0 <= X <= 3 and 0 <= Y <= 3.
Table size: 1 * 1 <= S * S <= 1024 * 1024
Cell value V at any time: 0 <= V <= 32767
Update amount: -32768 <= A <= 32767
No of instructions in input: 3 <= U <= 60002
Maximum number of phones in the whole table: M= 2^30
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
题目大意:
给定矩阵大小,可以更新矩阵中的某些数,要求输出某个范围内的所有数之和。
#include<stdio.h>
#include<string.h>
#define lowbit(x) x&(-x)
#define maxn 1025
int c[maxn][maxn];
int n;
void add(int x,int y,int a)
{for( int i = x; i <=n; i += lowbit(i)){for( int j = y; j <=n; j += lowbit(j)){c[i][j]+=a;}}
}
int sum( int l,int r )
{int ans = 0;for( int i = l; i > 0; i -= lowbit(i) ){for( int j = r; j > 0; j -=lowbit(j)){ans+=c[i][j];}}return ans;
}
int main()
{int i,j,k;scanf("%d%d",&k,&n);memset(c,0,sizeof(c));int op;while(~scanf("%d",&op)){if(op>=3) break;if(op == 1){int x,y,a;scanf("%d%d%d",&x,&y,&a);add(x+1,y+1,a);}else if(op == 2){int l,r,b,t;scanf("%d%d%d%d",&l,&b,&r,&t);l++,b++,r++,t++;printf("%d\n",sum(r,t) - sum(r,b-1) - sum(l-1, t) + sum(l-1, b-1));}}
}
这篇关于树状数组模板+poj1195(二维树状数组)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!