Stage4 - Needle
Elleryqueen · · 题解
作为验题人,有理由来写一篇题解。
首先肯定要先将这些刺进行排序,于是按照直觉以
于是可以想到线段树。使用两棵线段树,第一棵用来维护每一行
最后一个限制就是
如此看来,遍历所有点的复杂度为
#include<bits/stdc++.h>
#define fir first
#define sed second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=3e5+10;
int T,id,n,d;
struct node
{
int xx,yy;
int type;
bool operator<(const node aa)const
{
if(xx==aa.xx) return yy>aa.yy;
else return xx<aa.xx;
}
}a[N];
struct Node
{
int l,r;
int si,add_si;
LL val,add_val;
int tag;
};
int b1[N],b2[N],c[N];
int tot;
map<int,int> mp1,mp2;
int cnt1,cnt2;
LL ans;
struct Tree
{
Node tr[N*4];
void push_up(int pos)
{
tr[pos].si=tr[pos<<1].si+tr[pos<<1|1].si;
tr[pos].val=tr[pos<<1].val+tr[pos<<1|1].val;
}
void push_del(int pos,int val)
{
tr[pos].val=tr[pos].val-(LL)tr[pos].si*val;
tr[pos].tag+=val;
}
void push_si(int pos,int val)
{
tr[pos].si+=val;
tr[pos].add_si+=val;
}
void push_val(int pos,LL val)
{
tr[pos].val+=val;
tr[pos].add_val+=val;
}
void push_down(int pos)
{
if(tr[pos].tag)
{
push_del(pos<<1,tr[pos].tag);
push_del(pos<<1|1,tr[pos].tag);
tr[pos].tag=0;
}
if(tr[pos].add_si)
{
push_si(pos<<1,tr[pos].add_si);
push_si(pos<<1|1,tr[pos].add_si);
tr[pos].add_si=0;
}
if(tr[pos].add_val)
{
push_val(pos<<1,tr[pos].add_val);
push_val(pos<<1|1,tr[pos].add_val);
tr[pos].add_val=0;
}
}
void build(int pos,int l,int r)
{
if(l>r) return ;
tr[pos].l=l,tr[pos].r=r;
tr[pos].si=tr[pos].val=0;
tr[pos].tag=0;
if(l==r)
{
tr[pos].si=c[l];
return ;
}
int mid=l+r>>1;
build(pos<<1,l,mid);
build(pos<<1|1,mid+1,r);
push_up(pos);
}
int query_si(int pos,int l,int r)
{
if(tr[pos].l>=l&&tr[pos].r<=r)
return tr[pos].si;
push_down(pos);
int mid=tr[pos].l+tr[pos].r>>1;
int sum=0;
if(mid>=l) sum+=query_si(pos<<1,l,r);
if(mid<r) sum+=query_si(pos<<1|1,l,r);
return sum;
}
LL query_val(int pos,int l,int r)
{
if(tr[pos].l>=l&&tr[pos].r<=r){
return tr[pos].val;
}
push_down(pos);
int mid=tr[pos].l+tr[pos].r>>1;
LL sum=0;
if(mid>=l) sum+=query_val(pos<<1,l,r);
if(mid<r) sum+=query_val(pos<<1|1,l,r);
return sum;
}
void modify_si(int pos,int xx,int val)
{
if(tr[pos].l==xx&&tr[pos].r==xx){
tr[pos].si+=val;
return ;
}
push_down(pos);
int mid=tr[pos].l+tr[pos].r>>1;
if(mid>=xx) modify_si(pos<<1,xx,val);
else modify_si(pos<<1|1,xx,val);
push_up(pos);
}
void modify_val(int pos,int xx,LL val)
{
if(tr[pos].l==xx&&tr[pos].r==xx){
tr[pos].val+=val;
return ;
}
push_down(pos);
int mid=tr[pos].l+tr[pos].r>>1;
if(mid>=xx) modify_val(pos<<1,xx,val);
else modify_val(pos<<1|1,xx,val);
push_up(pos);
}
void modify(int pos,int l,int r)
{
if(tr[pos].l>=l&&tr[pos].r<=r){
push_del(pos,1);
return ;
}
push_down(pos);
int mid=tr[pos].l+tr[pos].r>>1;
if(mid>=l) modify(pos<<1,l,r);
if(mid<r) modify(pos<<1|1,l,r);
push_up(pos);
}
}tr1,tr2;
deque<PII > q;
int main()
{
scanf("%d %d",&T,&id);
while(T--)
{
tot=0,cnt1=cnt2=0;
ans=0;
mp1.clear();
mp2.clear();
while(!q.empty()) q.pop_front();
scanf("%d %d",&n,&d);
for(int i=1;i<=n;i++)
{
int xx,yy;
char op[3];
scanf("%d %d",&xx,&yy);
scanf("%s",op);
if(op[0]=='R'){
a[++tot]={xx,yy,1};
b1[tot]=xx,b2[tot]=yy;
}
else if(op[0]=='L'){
a[++tot]={xx,yy,2};
b1[tot]=xx,b2[tot]=yy;
}
else if(op[0]=='U'){
a[++tot]={xx,yy,3};
b1[tot]=xx,b2[tot]=yy;
}
}
sort(a+1,a+1+tot);
sort(b1+1,b1+1+tot);
sort(b2+1,b2+1+tot);
for(int i=1;i<=tot;i++){
if(i==1||b1[i]!=b1[i-1]) mp1[b1[i]]=++cnt1;
if(i==1||b2[i]!=b2[i-1]) mp2[b2[i]]=++cnt2;
}
for(int i=1;i<=cnt2;i++) c[i]=0;
tr1.build(1,1,cnt2);
for(int i=1;i<=tot;i++){
if(a[i].type==3) c[mp2[a[i].yy]]++;
}
tr2.build(1,1,cnt2);
for(int i=1;i<=tot;i++){
if(a[i].type==1){
int u=mp2[a[i].yy];
if(u==1) continue ;
int sum=tr2.query_si(1,1,u-1);
tr1.modify_val(1,u,(LL)sum);
tr1.modify_si(1,u,1);
q.push_back(make_pair(a[i].xx,a[i].yy));
}else if(a[i].type==2){
while(!q.empty())
{
if(a[i].xx-q.front().fir>d){
int u=mp2[q.front().sed];
if(u>1){
int sum=tr2.query_si(1,1,u-1);
tr1.modify_val(1,u,(LL)sum*-1LL);
tr1.modify_si(1,u,-1);
}
q.pop_front();
}else break ;
}
int u=mp2[a[i].yy];
if(u==1) continue ;
LL sum=tr1.query_val(1,1,u-1);
ans+=sum;
}else{
int u=mp2[a[i].yy];
tr2.modify_si(1,u,-1);
if(u==cnt2) continue ;
tr1.modify(1,u+1,cnt2);
}
}
printf("%lld\n",ans);
}
return 0;
}