这题可以用线段树离散化做,用二维树状数组做了一下,不懂得可以看一下这篇文章:http://www.java3z.com/cwbwebhome/article/article1/1369.html?id=4804
题意:
给你一个s*s的正方形区域,先输入一个x,若x==0,则再输入一个s,若x==1,则输入x,y,a,表示矩阵中(x,y)这点的值加上a,若x==2,输入l,b,r,t,代表以左上角的点(l,b)右下角的点(r,t),求这一片矩形内的矩阵元素之和,若x==3则结束此次程序
就是最基础的二维树状数组的应用,修改单点的值,并且快速求区间和
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #include<cctype> #define ll long long #define LL __int64 #define eps 1e-8 //const ll INF=9999999999999; #define inf 0xfffffff using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int> P; //vector<pair<int,int>> ::iterator iter; // //map<ll,int>mp; //map<ll,int>::iterator p; int n; int c[1000 + 35][1000 + 35]; void clear() { memset(c,0,sizeof(c)); } int lowbit(int x) { return x&(-x); } void add(int x,int y,int value) { int i = y; while(x <= n) { y = i; while(y <= n) { c[x][y] += value; y += lowbit(y); } x += lowbit(x); } } int get_sum(int x,int y) { int sum=0,i = y; while(x > 0) { y = i; while(y > 0) { sum += c[x][y]; y -= lowbit(y); } x -= lowbit(x); } return sum; } int main() { int x; while(true) { scanf("%d",&x); if(x == 0) { scanf("%d",&n); n++; clear(); } else if(x == 1) { int x,y,a; scanf("%d %d %d",&x,&y,&a); add(++x,++y,a);//矩阵行列标由0开始要处理掉 } else if(x == 2) { int l,b,r,t; scanf("%d %d %d %d",&l,&b,&r,&t); l++,b++,r++,t++;//处理行列标 int ans = 0; //int a1 = get_sum(r,b-1); //int a2 = get_sum(l-1,b-1); //int a3 = get_sum(r,t); //int a4 = get_sum(l-1,t); ans = get_sum(r,t) - get_sum(l-1,t) - get_sum(r,b-1) + get_sum(l-1,b-1); printf("%d\n",ans); } else break; } return 0; }
POJ1195 Mobile phones 二维树状数组的应用,码迷,mamicode.com
时间: 2024-10-29 19:05:43