2019杭电暑假多校9:Rikka with Cake【扫描线+树状数组】

题目:

2019 Multi-University Training Contest 9:Rikka with Cake

题意:

给定K条射线,问将N*M的矩形分成了多少块

分析:

发现每一个交点都会产生一个块,因为每条都是射线,猜测答案为交点的个数+1,知道这个就十分套路了;扫描横线,计算每条横线产生的贡献;具体做法:把横线拆成{L,R,h},每条竖线拆成两个点,(下面的点){x,y,h1,1}和(上面的点){x,y,h2,-1},代表的意思是这条竖线贡献[h1,h2)这个区间的扫描线;然后按h排序,依次扫描,如果当前扫到的是点,就把它的值加到它的X坐标上;如果扫到的是一条横线,就只需统计【L,R】的和就好了,所以用树状数组维护X数组的区间和;注意排序的时候h相同时,优先点,后横线

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int maxn = 2e5+15;
int T,n,m,k,x,y,cnt,cntx;
char op;
struct point{
    int f,L,R,id,v;
}p[maxn<<1];
bool cmp(point a,point b){
    if(a.id == b.id) return a.f < b.f;
    return a.id < b.id;
}
int tr[maxn<<1],X[maxn<<1];
int getid(int x){
    return lower_bound(X+1,X+cntx,x)-X;
}
void init(){
    X[cntx++] = n; sort(X+1,X+cntx); 
    cntx = unique(X+1,X+cntx)-X;
    sort(p,p+cnt,cmp);
    for(int i = 0;i <= cntx; ++i) tr[i] = 0;
}
inline int lowbit(int x){
    return x&(-x);
}
void updata(int pos,int val){
    while(pos <= cntx){
        tr[pos] += val;
        pos += lowbit(pos);
    }
}
LL query(int pos){
    LL res = 0;
    while(pos){
        res += tr[pos];
        pos -= lowbit(pos);
    }
    return res;
}
LL solve(){
    init(); LL ans = 0;
    for(int i = 0;i < cnt; ++i){
        if(p[i].f == 0) updata(getid(p[i].L),p[i].v);
        else ans += query(getid(p[i].R))-query(getid(p[i].L));
    }
    return ans + 1;
}
int main(){
    scanf("%d",&T);
    while(T--){
        cnt = 0; cntx = 2;
        scanf("%d %d %d",&n,&m,&k);
        for(int i = 0;i < k; ++i){
            scanf("%d %d %c",&x,&y,&op);
            if(op == 'U') p[cnt++] = (point){0,x,y,y,1};
            else if(op == 'D'){
                p[cnt++] = (point){0,x,y,0,1};
                p[cnt++] = (point){0,x,y,y+1,-1};
            }
            else if(op == 'L') p[cnt++] = (point){1,0,x,y,0};
            else p[cnt++] = (point){1,x-1,n,y,0},X[cntx++] = x-1;
            X[cntx++] = x;
        }
        printf("%I64d\n",solve());
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值