线段树
/*
Please write complete compilable code.
Read input from standard input (STDIN) and print output to standard output(STDOUT).
For more details, please check http://www.interviewstreet.com/recruit/challenges/faq/view#stdio
*/
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <string>
#include <map>
#include <set>
#include <fstream>
using namespace std;
typedef long long ll;
const int MAXN = 100010;
const int QUADRANT = 4;
int ans[QUADRANT];
inline int get_quadrant(int x, int y){
 if(x > 0){
 if(y > 0)return 0;
 return 3;
 }
 if(y > 0)return 1;
 return 2;
}
struct sst_t{
 int st, ed, stat[4], x, y;
 sst_t(){st = ed = x = y = 0;}
 sst_t(int _st, int _ed){
 st = _st;
 ed = _ed;
 x = y = 0;
 }
}sst[MAXN * 3];
inline void update(int r){
 for(int i = 0; i < QUADRANT; ++i)
 sst[r].stat[i] = sst[r << 1].stat[i] + sst[(r << 1) + 1].stat[i];
}
inline void down(int r){
 int le = r * 2, ri = r * 2 + 1;
 if(sst[r].x){
 sst[le].x ^= 1;
 swap(sst[le].stat[0], sst[le].stat[3]);
 swap(sst[le].stat[1], sst[le].stat[2]);
sst[ri].x ^= 1;
 swap(sst[ri].stat[0], sst[ri].stat[3]);
 swap(sst[ri].stat[1], sst[ri].stat[2]);
 
 sst[r].x = 0;
 }
 if(sst[r].y){
 sst[le].y ^= 1;
 swap(sst[le].stat[0], sst[le].stat[1]);
 swap(sst[le].stat[2], sst[le].stat[3]);
 
 sst[ri].y ^= 1;
 swap(sst[ri].stat[0], sst[ri].stat[1]);
 swap(sst[ri].stat[2], sst[ri].stat[3]);
 
 sst[r].y = 0;
 }
}
void build(int r, int st, int ed){
 sst[r] = sst_t(st, ed);
 if(st == ed){
 int x, y;
 scanf("%d %d", &x, &y);
 memset(sst[r].stat, 0, sizeof(sst[r].stat));
 sst[r].stat[get_quadrant(x,y)] = 1;
 return ;
 }
 int mid = (st + ed) / 2;
 build(r * 2, st, mid);
 build(r * 2 + 1, mid + 1, ed);
 update(r);
}
void adjust(int r, int st, int ed, int xy){
 /* xy = 0 Reflect all points between point st and ed both including along the X axis
 xy = 1 Reflect all points between point st and ed both including along the Y axis
 */
 if(sst[r].st > ed || sst[r].ed < st)return ;
 if(sst[r].st >= st && sst[r].ed <= ed){
 if(!xy){
 sst[r].x ^= 1;
 swap(sst[r].stat[0], sst[r].stat[3]);
 swap(sst[r].stat[1], sst[r].stat[2]);
 }else {
 sst[r].y ^= 1;
 swap(sst[r].stat[0], sst[r].stat[1]);
 swap(sst[r].stat[2], sst[r].stat[3]);
 }
 return ;
 }
 if(sst[r].x + sst[r].y != 0){
 down(r);
 }
 int mid = (sst[r].st + sst[r].ed) / 2;
 if(st <= mid){
 adjust(r * 2, st, ed, xy);
 }
 if(ed > mid){
 adjust(r * 2 + 1, st, ed, xy);
 }
 update(r);
}
void check(int r, int st, int ed){
 if(sst[r].st > ed || sst[r].ed < st)return ;
 if(sst[r].st >= st && sst[r].ed <= ed){
 for(int i = 0; i < QUADRANT; ++i)
 ans[i] += sst[r].stat[i];
 return;
 }
 if(sst[r].x + sst[r].y != 0){
 down(r);
 }
 int mid = (sst[r].st + sst[r].ed) / 2;
 if(st <= mid){
 check(r * 2, st, ed);
 }
 if(ed > mid){
 check(r * 2 + 1, st, ed);
 }
}
void print_tree(int r){
 printf("tree %d, [%d %d], %d %d\n", r, sst[r].st, sst[r].ed, sst[r].x, sst[r].y);
 printf("\t\t[%d,%d,%d,%d]\n", sst[r].stat[0],sst[r].stat[1],sst[r].stat[2],sst[r].stat[3]);
 if(sst[r].st == sst[r].ed)return;
 print_tree(r * 2);
 print_tree(r * 2 + 1);
}
int main()
{
 int n, m, st, ed;
 char ch;
 while(scanf("%d", &n) != EOF){
 build(1, 1, n);
// print_tree(1);
 scanf("%d", &m);
 while(m--){
 scanf(" %c %d %d", &ch, &st, &ed);
 if(ch == 'X'){
 adjust(1, st, ed, 0);
 }else if(ch == 'Y'){
 adjust(1, st, ed, 1);
 }else {
 memset(ans, 0, sizeof(ans));
 check(1, st, ed);
 printf("%d", ans[0]);
 for(int i = 1; i < QUADRANT; ++i)
 printf(" %d", ans[i]);
 printf("\n");
 }
 }
 }
 return 0;
}
 
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号