1. 程式人生 > >(二維樹狀數組)E - Stars

(二維樹狀數組)E - Stars

|| true main light fine play targe ble problem

E - Stars

題意:B表示點亮改點,D表示熄滅,Q查詢區間內亮的個數

Sample Input

5
B 581 145
B 581 145
Q 0 600 0 200
D 581 145
Q 0 600 0 200

AC代碼:

技術分享圖片
  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 #define c_1(a) scanf("%d",&a)
  5 #define c_2(a,b) scanf("%d%d",&a,&b)
  6 #define c_3(a,b,c) scanf("%d%d%d",&a,&b,&c)
  7
8 #define min_2(a,b) a<b?a:b 9 #define min_3(a,b,c) min_2(min_2(a,b),c) 10 #define max_2(a,b) a>b?a:b 11 #define max_3(a,b,c) max_2(max_2(a,b),c) 12 #define ll long long 13 #define rint register int 14 #define mem0(x) memset(x, 0, sizeof(x)) 15 #define mem1(x) memset(x, -1, sizeof(x)) 16
#define lowbit(x) x&-x 17 18 //freopen("input.txt", "r", stdin); 19 const double PI=acos(-1.0); 20 const int inf = 0x3f3f3f3f; 21 const ll inff = 0x3f3f3f3f3f3f3f3f; 22 const int mod=1000000007; 23 const int maxn=1e5+5; 24 25 //map<ll,ll>mp; 26 //set<ll>st; 27 //stack<>st; 28 //queue<>Q;
29 /***********************************************/ 30 int a[1003][1003]; 31 int c[1003][1003]; 32 33 void add(int x,int y,int p) 34 { 35 if(p==1) a[x][y]=1; 36 else a[x][y]=0; 37 int j=y; 38 while(x<=1001){ 39 y=j; 40 while(y<=1001){ 41 c[x][y]+=p; 42 y+=lowbit(y); 43 } 44 x+=lowbit(x); 45 } 46 } 47 48 ll summ(int x,int y) 49 { 50 if(x<0 || y<0) return 0; 51 ll ans=0; 52 int j=y; 53 while(x>0){ 54 y=j; 55 while(y>0){ 56 ans+=c[x][y]; 57 y-=lowbit(y); 58 } 59 x-=lowbit(x); 60 } 61 return ans; 62 } 63 64 int main() 65 { 66 int n; 67 c_1(n); 68 while(n--) 69 { 70 char s; 71 int x1,x2,y1,y2; 72 cin>>s; 73 if(s==B) 74 { 75 //cin>>x1>>x2; 76 scanf("%d%d",&x1,&x2); 77 x1++,x2++; 78 if(a[x1][x2]==0) add(x1,x2,1); 79 } 80 else if(s==D) 81 { 82 c_2(x1,x2); 83 x1++,x2++; 84 if(a[x1][x2]) add(x1,x2,-1); 85 } 86 else if(s==Q) 87 { 88 scanf("%d%d%d%d",&x1,&x2,&y1,&y2); 89 x1++,x2++,y1++,y2++; 90 int ans=0; 91 if(x1<x2){ 92 if(y1>y2)//4 93 ans=summ(x1-1,y2-1)-summ(x1-1,y1)-summ(x2,y2-1)+summ(x2,y1); 94 else 95 {//1 96 ans=summ(x1-1,y1-1)-summ(x1-1,y2)-summ(x2,y1-1)+summ(x2,y2); 97 } 98 99 } 100 else{ 101 if(y2>y1)//3 102 ans=summ(x2-1,y1-1)-summ(x1,y1-1)-summ(x2-1,y2)+summ(x1,y2); 103 else//2 104 ans=summ(x1,y1)-summ(x1,y2-1)-summ(x2-1,y1)+summ(x2-1,y2-1); 105 } 106 printf("%d\n",ans); 107 } 108 } 109 return 0; 110 }
View Code

二維樹狀數組維護代碼:

void add(int x,int y,int p)//在xy處修改,維護二維樹狀數組
{
	a[x][y]+=p;
	int j=y;
	while(x<=n){
		y=j;
		while(y<=n){
			c[x][y]+=p;
			y+=lowbit(y);
		}
		x+=lowbit(x);
	}
}
ll summ(int x,int y)//查詢00 到 xy 區間的和
{
	if(x<0 || y<0) return 0;
	ll ans=0;
	int j=y;
	while(x>0){
		y=j;
		while(y>0){
			ans+=c[x][y];
			y-=lowbit(y);
		}
		x-=lowbit(x);
	}
	return ans;
}
只是把一維變二維,一樣寫
下圖為此題筆記:(求兩點表示的區間和時)

技術分享圖片

(二維樹狀數組)E - Stars