hdu6681(线段树)

hdu6681

题意

在n*m的平面上有k条射线,问把这个平面切成多少块?

思路

预处理一下,按x左边排序,type=1表示开始的位置,type=2表示结束的位置,用线段树维护y轴,单点更新,区间查询.

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int tree[maxn<<2];
int c;
int n,m,q;
void built(int rt,int l,int r){
    tree[rt]=0;
    if(l==r) return ;
    int mid=(l+r)>>1;
    built(rt<<1,l,mid);
    built(rt<<1|1,mid+1,r);
}
void update(int pos,int val,int l=1,int r=c,int rt=1){
    if(l==r){
        tree[rt]+=val;
        return;
    }
    int mid=(l+r)>>1;
    if(pos<=mid) update(pos,val,l,mid,rt<<1);
    else update(pos,val,mid+1,r,rt<<1|1);
    tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
int query(int ql,int qr,int l=1,int r=c,int rt=1){
    if(ql<=l&&qr>=r) return tree[rt];
    int mid=(l+r)>>1;
    int ans=0;
    if(ql<=mid) ans+=query(ql,qr,l,mid,rt<<1);
    if(qr>mid) ans+=query(ql,qr,mid+1,r,rt<<1|1);
    return ans;
}
struct node{
    int x,y1,y2,type;
    bool operator <(const node& a) const {
        return x==a.x?type<a.type:x<a.x;
    }
}a[maxn*2];
int b[maxn];
int getid(int x) {
    return lower_bound(b + 1, b + c + 1, x) - b;
}
int main() {
    int _;scanf("%d", &_);
    while(_--) {
        scanf("%d%d%d", &n, &m, &q);
        int tot = 0;
        b[q+1] = 0, b[q+2] = m;
        for(int i=1;i<=q;i++){
            int x,y;char s[2];
            scanf("%d%d%s",&x,&y,s);
            b[i]=y;
            if(s[0]=='L'){
                a[++tot]={0,y,0,1};
                a[++tot]={x+1,y,0,2};
            }
            else if(s[0]=='R'){
                a[++tot]={x,y,0,1};
                a[++tot]={n+1,y,0,2};
            }
            else if(s[0]=='U'){
                a[++tot]={x,y,m,3};
            }
            else a[++tot]={x,0,y,3}; 
        }
        sort(a+1,a+tot+1);
        sort(b+1,b+q+3);
        c=unique(b+1,b+q+3)-b-1;
        built(1, 1, c);
        int ans = 1;
        for(int i = 1; i <= tot; ++i) {
            if(a[i].type == 1) update(getid(a[i].y1), 1);
            else if(a[i].type == 2)  update(getid(a[i].y1), -1);
            else  ans += query( getid(a[i].y1), getid(a[i].y2));
        }
        printf("%d\n", ans);
    }
    //system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值