线段树

/*
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;
}

你可能感兴趣的:(线段树)