Rikka with Mista 线段树求交点个数

   由于上下线段是不可能有交点的

   可以先看左右线段树,按照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\n",ans+1);
  }
  return 0;
}

 

posted @ 2019-08-20 20:21  bluefly-hrbust  阅读(203)  评论(0编辑  收藏  举报