【POJ 1656】 水题,不过抄了个二维线段树的代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
int num[2000001], cover[2000001];
void push(int idx, int lx, int rx, int ly, int ry)
{
 if (cover[idx] == -1) return;
 cover[idx * 4 + 1] = cover[idx * 4 + 2] = cover[idx * 4 + 3] = cover[idx * 4 + 4] = cover[idx];
 int mx = (lx + rx) >> 1, my = (ly + ry) >> 1;
 num[idx * 4 + 1] = cover[idx] * (mx - lx + 1) * (my - ly + 1);
 num[idx * 4 + 2] = cover[idx] * (mx - lx + 1) * (ry - my);
 num[idx * 4 + 3] = cover[idx] * (rx - mx) * (my - ly + 1);
 num[idx * 4 + 4] = cover[idx] * (rx - mx) * (ry - my);
 cover[idx] = -1;
}
void update(int idx)
{
 num[idx] = num[idx * 4 + 1] + num[idx * 4 + 2] + num[idx * 4 + 3] + num[idx * 4 + 4];
}
void insert(int idx, int lx, int rx, int ly, int ry, int Lx, int Rx, int Ly, int Ry, int w)
{
 if (Lx <= lx && Rx >= rx && Ly <= ly && Ry >= ry){
  cover[idx] = w;
  num[idx] = (rx - lx + 1) * (ry - ly + 1) * w;
  return;
  }
 push(idx, lx, rx, ly, ry);
 int mx = (lx + rx) >> 1, my = (ly + ry) >> 1;
 if (Lx <= mx && Ly <= my) insert(idx * 4 + 1, lx, mx, ly, my, Lx, Rx, Ly, Ry, w);
 if (Lx <= mx && Ry > my) insert(idx * 4 + 2, lx, mx, my + 1, ry, Lx, Rx, Ly, Ry, w);
 if (Rx > mx && Ly <= my) insert(idx * 4 + 3, mx + 1, rx, ly, my, Lx, Rx, Ly, Ry, w);
 if (Rx > mx && Ry > my) insert(idx * 4 + 4, mx + 1, rx, my + 1, ry, Lx, Rx, Ly, Ry, w);
 update(idx);
}
int query(int idx, int lx, int rx, int ly, int ry, int Lx, int Rx, int Ly, int Ry)
{
 if (Lx <= lx && Rx >= rx && Ly <= ly && Ry >= ry) return num[idx];
 push(idx, lx, rx, ly, ry);
 int mx = (lx + rx) >> 1, my = (ly + ry) >> 1, t = 0;
 if (Lx <= mx && Ly <= my) t += query(idx * 4 + 1, lx, mx, ly, my, Lx, Rx, Ly, Ry);
 if (Lx <= mx && Ry > my) t += query(idx * 4 + 2, lx, mx, my + 1, ry, Lx, Rx, Ly, Ry);
 if (Rx > mx && Ly <= my) t += query(idx * 4 + 3, mx + 1, rx, ly, my, Lx, Rx, Ly, Ry);
 if (Rx > mx && Ry > my) t += query(idx * 4 + 4, mx + 1, rx, my + 1, ry, Lx, Rx, Ly, Ry);
 return t;
}
 
int main()
{
 int Q, x, y, L;
 char op[100];
 memset(cover, 0xff, sizeof(cover));
 scanf("%d", &Q);
 while(Q--){
  scanf("%s%d%d%d", &op, &x, &y, &L);
  switch(op[0]){
   case 'B':insert(0, 1, 101, 1, 101, x, x + L - 1, y, y + L - 1, 1); break;
   case 'W':insert(0, 1, 101, 1, 101, x, x + L - 1, y, y + L - 1, 0); break;
   case 'T':printf("%d\n", query(0, 1, 101, 1, 101, x ,x + L - 1, y, y + L - 1)); break;
   }
  }
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值