1. 程式人生 > >POJ 2155

POJ 2155

one ret 二維 pla std math 線段 iostream pan

技術分享
 1 #include<iostream>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<queue>
 5 #include<algorithm>
 6 #include<cstdio>
 7 #define rep(i,a,n) for(i=a;i<=n;i++)
 8 #define per(i,a,n) for(i=n;i>=a;i--)
 9 #define scd1(a) scanf("%d",&a)
10 #define scd2(a,b) scanf("%d%d",&a,&b)
11
#define ll long long 12 #define mem(a,b) memset(a,b,sizeof a); 13 using namespace std; 14 15 const int maxn=1000; 16 int T,cnt=0,N,M; 17 int mt[maxn+5][maxn+5]; 18 char ist; 19 20 int lowbit(int num){ 21 return num&(-num); 22 } 23 24 void add(int x, int y, int d){ 25 while(x<=N){ 26 int
j=y; 27 while(j<=N){ 28 mt[x][j]+=d;j+=lowbit(j); 29 }x+=lowbit(x); 30 } 31 } 32 33 int sum(int x, int y){ 34 int ret=0; 35 while(x>0){ 36 int j=y; 37 while(j>0){ 38 ret+=mt[x][j];j-=lowbit(j); 39 } 40 x-=lowbit(x);
41 } 42 return ret; 43 } 44 45 int main(){ 46 scanf("%d",&T); 47 while(T--){ 48 mem(mt,0); 49 scanf("%d%d ",&N,&M); 50 int i; 51 rep(i,1,M){ 52 scanf("%c",&ist); 53 if(ist==C){ 54 int x1,x2,y1,y2; 55 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 56 add(x1,y1,1); 57 add(x1,y2+1,-1); 58 add(x2+1,y1,-1); 59 add(x2+1,y2+1,1); 60 } 61 else if(ist==Q){ 62 int x,y; 63 scd2(x,y); 64 int ans=sum(x,y); 65 printf("%d\n",ans%2); 66 } 67 getchar(); 68 } 69 if(T)printf("\n"); 70 } 71 }
View Code

題意描述: 給出一個矩陣每個點的初值, 每次操作可以對一個子矩陣內的值進行加減, 每次質詢要求給出矩陣中某個點的值.

就是一個裸的二維樹狀數組. 見代碼. 它的對偶題是POJ1195 Mobile Phones, 那個題是每次改一個點的值, 每次質詢要求給出一個子矩陣內的數值和. 代碼只要改一改就能過. 題解鏈接: http://www.cnblogs.com/LiXinze/p/7353451.html

當然這種題也可以用線段樹來做, 只不過稍微會麻煩一點.

POJ 2155