由于上下线段是不可能有交点的
可以先看左右线段树,按照y递增的顺序,对点进行排序。
升序构造,那么对于从某一点往下的射线,对于L,R进行区间覆盖,线段交点个数就是单点的被覆盖的次数。
降序构造,那么对于从某个点从下往上的射线,所有y坐标比期大的点都进行了区间覆盖,那么单点就是答案。
最近脑子不太好。。。思路一定要清晰啊。。。
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<vector> #define pii pair<int,int> #define pb push_back #define mp make_pair #define LL long long #define lson rt<<1 #define rson rt<<1|1 using namespace std; const int maxx = 2e5+6; struct node{ int l,r,laze; int w; }tree[maxx<<2]; vector<int>vx; vector<int>vy; struct Point{ int x,y; char op; }p[maxx]; int getx(int x){ return lower_bound(vx.begin(),vx.end(),x)-vx.begin()+1; } int gety(int x){ return lower_bound(vy.begin(),vy.end(),x)-vy.begin()+1; } void push_donw(int rt){ if (tree[rt].laze){ tree[lson].laze+=tree[rt].laze; tree[rson].laze+=tree[rt].laze; tree[lson].w+=tree[rt].laze*(tree[lson].r-tree[lson].l+1); tree[rson].w+=tree[rt].laze*(tree[rson].r-tree[rson].l+1); tree[rt].laze=0; } } void buildtree(int rt,int l,int r){ tree[rt].l=l; tree[rt].r=r; tree[rt].laze=0; tree[rt].w=0; if (l==r){ return ; } int mid=(l+r)>>1; buildtree(lson,l,mid); buildtree(rson,mid+1,r); } void update(int rt,int ql,int qr,int w){ int l=tree[rt].l; int r=tree[rt].r; if (ql<=l && r<=qr){ tree[rt].laze+=w; tree[rt].w+=w*(r-l+1); return; } int mid=(l+r)>>1; push_donw(rt); if (qr<=mid){ update(lson,ql,qr,w); }else if(ql>mid){ update(rson,ql,qr,w); }else { update(lson,ql,mid,w); update(rson,mid+1,qr,w); } tree[rt].w=tree[lson].w+tree[rson].w; } int query(int rt,int pos){ int l=tree[rt].l; int r=tree[rt].r; if (l==r){ return tree[rt].w; } int mid=(l+r)>>1; push_donw(rt); if (pos<=mid){ return query(lson,pos); }else { return query(rson,pos); } tree[rt].w=tree[lson].w+tree[rson].w; } bool cmp(Point a,Point b){ return a.y<b.y; } int main(){ int t; int n,m,k; scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&m,&k); vx.clear(); vy.clear(); for (int i=1;i<=k;i++){ scanf("%d%d %c",&p[i].x,&p[i].y,&p[i].op); vx.push_back(p[i].x); vy.push_back(p[i].y); } sort(vx.begin(),vx.end()); sort(vy.begin(),vy.end()); vx.erase(unique(vx.begin(),vx.end()),vx.end()); vy.erase(unique(vy.begin(),vy.end()),vy.end()); sort(p+1,p+1+k,cmp); int sz=vx.size(); buildtree(1,1,sz); LL ans=0; for (int i=1;i<=k;i++){ if (p[i].op=='D'){ ans+=query(1,getx(p[i].x)); }else if (p[i].op=='L'){ update(1,1,getx(p[i].x),1); }else if (p[i].op=='R'){ update(1,getx(p[i].x),sz,1); } } buildtree(1,1,sz); for (int i=sz;i>=1;i--){ if (p[i].op=='U'){ ans+=query(1,getx(p[i].x)); }else if (p[i].op=='L'){ update(1,1,getx(p[i].x),1); }else if (p[i].op=='R'){ update(1,getx(p[i].x),sz,1); } } printf("%d ",ans+1); } return 0; }