树状数组的修改+查询

Color the ball

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 29305    Accepted Submission(s): 14264


Problem Description
N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
 
Input
每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。
当N = 0,输入结束。
 
Output
每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。
 
Sample Input
3 1 1 2 2 3 3 3 1 1 1 2 1 3 0
 
Sample Output
1 1 1 3 2 1
 
Author
8600
 
Source
 
 
//hdu  1556
//区间修改、单点查询
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <set> #include <map> using namespace std; #define ll long long #define lowbit(x) x&(-x) const int N=1e5+9; ll a[N],c[N]; ll n,x,y; void update(ll x,ll num){ while(x<=n){ c[x]+=num; x+=lowbit(x); } } ll getsum(ll x){ ll sum = 0; while(x>0){ sum+=c[x]; x-=lowbit(x); } return sum; } int main() { while(~scanf("%lld",&n),n){ for(ll i = 1 ;i <=n+9;i++){ a[i]=0; c[i] =0; } for(ll i =0;i<n;i++){ scanf("%lld%lld",&x,&y); update(x,1); update(y+1,-1); } for(ll i =1;i<=n;i++){ printf("%lld%c",getsum(i),i==n?' ':' '); } } return 0; }

//POJ   2155

Matrix
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 33412   Accepted: 12101

Description

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1 <= i, j <= N). 

We can change the matrix in the following way. Given a rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2), we change all the elements in the rectangle by using "not" operation (if it is a '0' then change it into '1' otherwise change it into '0'). To maintain the information of the matrix, you are asked to write a program to receive and execute two kinds of instructions. 

1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) changes the matrix by using the rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2). 
2. Q x y (1 <= x, y <= n) querys A[x, y]. 

Input

The first line of the input is an integer X (X <= 10) representing the number of test cases. The following X blocks each represents a test case. 

The first line of each block contains two numbers N and T (2 <= N <= 1000, 1 <= T <= 50000) representing the size of the matrix and the number of the instructions. The following T lines each represents an instruction having the format "Q x y" or "C x1 y1 x2 y2", which has been described above. 

Output

For each querying output one line, which has an integer representing A[x, y]. 

There is a blank line between every two continuous test cases. 

Sample Input

1
2 10
C 2 1 2 2
Q 2 2
C 2 1 2 1
Q 1 1
C 1 1 2 1
C 1 2 1 2
C 1 1 2 2
Q 1 1
C 1 1 2 1
Q 2 1

Sample Output

1
0
0
1

Source

 

 

 // 区间修改、单点查询
1
#include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <set> 6 #include <map> 7 using namespace std; 8 #define ll long long 9 #define lowbit(x) x&(-x) 10 /* 11 一维的进行互补操作(1变成0,0变成1),[a,b] 只需要a:+1,b+1:+1 12 求第K个数的值,只需要getsum(k)%2即可 13 二维的要用到容斥定理:(x1,y1),(x2,y2) 14 (x1,y1,1),(x1,y2+1,1),(x2+1,y1,1),(x2+1,y2+1,1) 15 求(x,y)的值,只需要getsum(x,y)%2即可。 16 */ 17 const int N = 1e3+9; 18 int x,n,t; 19 char s[5]; 20 int a[N][N],c[N][N]; 21 void init(int n){ 22 for(int i =0;i<=n;i++){ 23 for(int j =0;j<=n;j++){ 24 a[i][j] = 0; 25 c[i][j] = 0; 26 } 27 } 28 } 29 void update(int x,int y,int num){ 30 for(int i =x;i<=n;i+=lowbit(i)){ 31 for(int j =y;j<=n;j+=lowbit(j)){ 32 c[i][j]+=num; 33 } 34 } 35 } 36 int getsum(int x,int y){ 37 int sum = 0; 38 for(int i =x;i>0;i-=lowbit(i)){ 39 for(int j =y;j>0;j-=lowbit(j)){ 40 sum += c[i][j]; 41 } 42 } 43 return sum ; 44 } 45 int main() 46 { 47 scanf("%d",&x); 48 while(x--){ 49 scanf("%d%d",&n,&t); 50 init(n); 51 int x1,y1,x2,y2; 52 for(int i = 0;i<t;i++){ 53 scanf("%s",s); 54 if(s[0]=='C'){ 55 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 56 update(x1,y1,1); 57 update(x1,y2+1,1); 58 update(x2+1,y1,1); 59 update(x2+1,y2+1,1); 60 } 61 else{ 62 scanf("%d%d",&x1,&y1); 63 printf("%d ",getsum(x1,y1)%2); 64 } 65 } 66 if(x>0) printf(" "); 67 } 68 return 0; 69 }

 //POJ   1656

Counting Black
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 11630   Accepted: 7501

Description

There is a board with 100 * 100 grids as shown below. The left-top gird is denoted as (1, 1) and the right-bottom grid is (100, 100). 

We may apply three commands to the board: 

1. WHITE x, y, L // Paint a white square on the board,
// the square is defined by left-top grid (x, y)
// and right-bottom grid (x+L-1, y+L-1)

2. BLACK x, y, L // Paint a black square on the board,
// the square is defined by left-top grid (x, y)
// and right-bottom grid (x+L-1, y+L-1)

3. TEST x, y, L // Ask for the number of black grids
// in the square (x, y)- (x+L-1, y+L-1)

In the beginning, all the grids on the board are white. We apply a series of commands to the board. Your task is to write a program to give the numbers of black grids within a required region when a TEST command is applied. 

Input

The first line of the input is an integer t (1 <= t <= 100), representing the number of commands. In each of the following lines, there is a command. Assume all the commands are legal which means that they won't try to paint/test the grids outside the board.

Output

For each TEST command, print a line with the number of black grids in the required region.

Sample Input

5
BLACK 1 1 2
BLACK 2 2 2
TEST 1 1 3
WHITE 2 1 1
TEST 1 1 3

Sample Output

7
6
//单点修改+区间查询
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <set> #include <map> using namespace std; #define ll long long #define lowbit(x) x&(-x) const int N = 1e2+5; int a[N][N],c[N][N]; int t; char s[10]; int x,y,l; void update(int x,int y,int num){ for(int i =x;i<=100;i+=lowbit(i)){ for(int j =y;j<=100;j+=lowbit(j)){ c[i][j]+=num; } } } int getsum(int x,int y){ int sum = 0; for(int i =x;i>0;i-=lowbit(i)){ for(int j = y;j>0;j-=lowbit(j)){ sum += c[i][j] ; } } return sum ; } int main() { scanf("%d",&t); while(t--){ scanf("%s",s); if(s[0]=='B'){ scanf("%d%d%d",&x,&y,&l); for(int i =x;i<=x+l-1;i++){ for(int j =y;j<=y+l-1;j++){ if(!a[i][j]){ a[i][j] = 1; update(i,j,1); } } } } else if(s[0]=='W'){ scanf("%d%d%d",&x,&y,&l); for(int i = x;i <= x+l-1;i++){ for(int j = y;j <= y+l-1;j++){ if(a[i][j] == 1 ){ a[i][j] = 0; update(i,j,-1); } } } } else{ scanf("%d%d%d",&x,&y,&l); printf("%d ",getsum(x-1,y-1)+getsum(x+l-1,y+l-1)-getsum(x-1,y+l-1)-getsum(x+l-1,y-1)); } } return 0; }

原文地址:https://www.cnblogs.com/tingtin/p/9902412.html