树状数组的修改+查询
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,输入结束。
当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?'\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].
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.
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.
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\n",getsum(x1,y1)%2); 64 } 65 } 66 if(x>0) printf("\n"); 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:
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.
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\n",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; }