F. Cutting Game
题解
我一开始想着二位前缀和+模拟,但是看到ab发现空间不够
观察到nm的数据范围限制
也就是点和查询的数量限制,考虑用优先队列把各个方向的点存起来以表示各个点的使用顺序,再用map嵌套表示各个点的使用情况
空间复杂度 \(O(n)\) 时间复杂度 \(O(T(mlogn+nlogn))\)
code
#include<bits/stdc++.h>
using namespace std;
struct nodel
{
int x,y;
bool operator<(const nodel &b)const {return b.y<y;}
};
struct noder
{
int x,y;
bool operator<(const noder &b)const {return b.y>y;}
};
struct nodeu
{
int x,y;
bool operator<(const nodeu &b)const {return b.x<x;}
};
struct noded
{
int x,y;
bool operator<(const noded &b)const {return b.x>x;}
};
map<int,map<int,int > >vis;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
int a,b,n,m;
cin>>a>>b>>n>>m;
priority_queue<nodel> l;
priority_queue<noder> r;
priority_queue<nodeu> u;
priority_queue<noded> d;
while(n--)
{
int x,y;
cin>>x>>y;
vis[x][y]=1;
l.push({x,y});
r.push({x,y});
u.push({x,y});
d.push({x,y});
}
int x1=1,y1=1,x2=a,y2=b;
int flag=1;
int ansa=0,ansb=0;
while(m--)
{
char op;
int k;
cin>>op>>k;
int cnt=0;
if(op=='U')
{
x1+=k;
while(u.size())
{
int x=u.top().x,y=u.top().y;
if(x<x1)
{
if(vis[x][y]) cnt++;
vis[x][y]=0;
u.pop();
}
else break;
}
}
else if(op=='D')
{
x2-=k;
while(d.size())
{
int x=d.top().x,y=d.top().y;
if(x>x2)
{
if(vis[x][y]) cnt++;
vis[x][y]=0;
d.pop();
}
else break;
}
}
else if(op=='R')
{
y2-=k;
while(r.size())
{
int x=r.top().x,y=r.top().y;
if(y>y2)
{
if(vis[x][y]) cnt++;
vis[x][y]=0;
r.pop();
}
else break;
}
}
else
{
y1+=k;
while(l.size())
{
int x=l.top().x,y=l.top().y;
if(y<y1)
{
if(vis[x][y]) cnt++;
vis[x][y]=0;
l.pop();
}
else break;
}
}
if(flag) ansa+=cnt;
else ansb+=cnt;
flag^=1;
}
cout<<ansa<<" "<<ansb<<"\n";
vis.clear();
}
return 0;
}