智子入侵
【题目背景】
三体发现了人类。
在疲于应付三个无法预测规律的太阳的时候,地球是他们唯一的希望。
为了限制住人类的基础物理研究,避免 300 年的技术爆炸,智子到达了地球。
目标:所有的粒子对撞机。
【题目描述】
作为三体人的科学执政官,元首需要你想他汇报智子每一次攻击的成果。军事执政官
已经把智子的攻击计划提交给你,而人类的一举一动也在智子的监视之下。你需要计算出
每一次智子的攻击能够摧毁多少个对撞机。
把地球的地面抽象为一个网格平面,对撞机占据一块边界与坐标轴平行的矩形地面,
而智子每次只攻击一个格子。一个对撞机的任意一部分被攻击到,则整个对撞机被彻底摧
毁。
需要注意的是,对撞机之间可以重叠。
【输入】(collider.in)
文件的第一行有一个正整数 n,表示你所知道的 n 个事件。接下来的 n 行描述 n 个事
件(它们按输入的顺序依次发生)。事件只有两种:Build & Destroy(B & D)。
第 i+1 行(i>=1)描述了第 i 个事件,每一行的开头是一个字母,表示事件的种类,格
式如下:
B x1 y1 x2 y3:建造一个对撞机,左下角坐标为(x1,y1),右上角坐标为(x2,y2)
D x1 y1:智子进行了一次攻击,坐标为(x1,y1)
注意,坐标均为正整数。B 和 D 为大写。
【输出】(collider.out)
对于每一次智子的攻击,在单独的一行里输出这一次攻击摧毁掉的对撞机个数。
【样例输入】
4
B 1 1 3 3
B 3 3 5 5
D 3 3
D 3 3
【样例输出】
2
0
【数据规模】
25%的数据 n<=1000 x,y<=500
50%的数据 n<=10000 x,y<=500
100%的数据 n<=200000 x,y<=1500
#include
#include
#include
using namespace std;
const int N=200010,M=1510,K=25000010;
struct Data
{
int tp,x1,y1,x2,y2;
} q[N];
int cnt,rt[M<<2],ch[K][2],Min[K];
int Q,ans[N];
char tp[10];
#define mid ((l+r)>>1)
int NewNode()
{
Min[++cnt]=K;
return cnt;
}
void Inserty(int &x,int l,int r,int gy,int key)
{
if(!x)x=NewNode();
if(l==r)
{
Min[x]=min(Min[x],key);
return;
}
if(mid>=gy)Inserty(ch[x][0],l,mid,gy,key);
else Inserty(ch[x][1],mid+1,r,gy,key);
Min[x]=min(Min[ch[x][0]],Min[ch[x][1]]);
}
void Insertx(int x,int l,int r,int gx,int gy,int key)
{
Inserty(rt[x],1,1500,gy,key);
if(l==r)return;
if(mid>=gx)Insertx(x<<1,l,mid,gx,gy,key);
else Insertx(x<<1|1,mid+1,r,gx,gy,key);
}
int Queryy(int x,int l,int r,int y1,int y2)
{
if(!x)return K;
if(l>=y1&&r<=y2)return Min[x];
int ret=K;
if(mid>=y1)ret=min(ret,Queryy(ch[x][0],l,mid,y1,y2));
if(midx][1],mid+1,r,y1,y2));
return ret;
}
int Queryx(int x,int l,int r,int x1,int x2,int y1,int y2)
{
if(l>=x1&&r<=x2)return Queryy(rt[x],1,1500,y1,y2);
int ret=K;
if(mid>=x1)ret=min(ret,Queryx(x<<1,l,mid,x1,x2,y1,y2));
if(midx<<1|1,mid+1,r,x1,x2,y1,y2));
return ret;
}
int main()
{
freopen("collider.in","r",stdin);
freopen("collider.out","w",stdout);
scanf("%d",&Q);
Min[0]=K;
for(int i=1; i<=Q; i++)
{
scanf("%s",tp);
if(tp[0]=='B')
{
q[i].tp=1;
scanf("%d%d",&q[i].x1,&q[i].y1);
scanf("%d%d",&q[i].x2,&q[i].y2);
}
if(tp[0]=='D')
{
q[i].tp=2;
scanf("%d%d",&q[i].x1,&q[i].y1);
}
}
for(int i=Q; i>=1; i--)
{
if(q[i].tp==2)
Insertx(1,1,1500,q[i].x1,q[i].y1,i);
else
{
int ret=Queryx(1,1,1500,q[i].x1,q[i].x2,q[i].y1,q[i].y2);
if(ret!=K)ans[ret]+=1;
}
}
for(int i=1; i<=Q; i++)
if(q[i].tp==2)
printf("%d\n",ans[i]);
return 0;
}