【BZOJ1818】内部白点

news/2024/11/16 8:39:29/

链接:BZOJ1818

解法:树状数组

题意转化为求线段的交点个数。
先将任一坐标离散化,这里以 x x 为例。之后将 x y y 坐标分别排序,求出这些线段。以样例为例,如下图:( x 坐标已离散化,只有在同一横/纵坐标上出现多个点时才会出现线段。)
绿色与蓝色是线段
将线段分两种,横与竖。
将横线段拆为两个点,竖线段不变。然后将这些东西排序。从左至右扫描(若是离散化 y y 坐标则从下至上),扫描到横线段的左端点时,将该横线段的横坐标处的位置 +1 ,扫描到横线段的右端点则 1 − 1 ;扫描到竖线段则查询线段的上下端点,加入答案。区间查询用树状数组维护即可。
细节很多,实现时心态很容易崩( cmp c m p 函数别打错)

代码

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>using namespace std;struct data{int x,y,i;data():x(0),y(0),i(0){}data(int a,int b,int j):x(a),y(b),i(j){}
};struct upd{int t,x,l,r;upd(){}upd(int u,int y,int a,int b):t(u),x(y),l(a),r(b){}friend bool operator<(const upd &u1,const upd &u2){if(u1.x==u2.x)return u1.t<u2.t;else return u1.x<u2.x;}
};int n,rnk[100002],sum[100002];
long long ans;
data dt[100002];
vector<upd> V;inline bool cmp1(const data &dt1,const data &dt2){if(dt1.x==dt2.x)return dt1.y<dt2.y;return dt1.x<dt2.x;}inline bool cmp2(const data &dt1,const data &dt2){if(dt1.y==dt2.y)return dt1.x<dt2.x;return dt1.y<dt2.y;}inline int lowbit(int x){return x&-x;}void update(int k,int x){for(int i=k;i<=n;i+=lowbit(i))sum[i]+=x;}int query(int k){int res=0;for(int i=k;i>0;i-=lowbit(i))res+=sum[i];return res;}int main(){scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d%d",&dt[i].x,&dt[i].y),dt[i].i=i;sort(dt+1,dt+n+1,cmp1);dt[0].x=2147483647;for(int i=1,j=0;i<=n;++i)if(dt[i].x==dt[i-1].x)rnk[dt[i].i]=j;else rnk[dt[i].i]=++j;sort(dt+1,dt+n+1,cmp2);for(int i=1;i<=n;++i){int j=i;if(dt[j+1].y==dt[j].y)++j;if(i!=j)V.push_back(upd(1,dt[i].y,rnk[dt[i].i],rnk[dt[j].i]));}sort(dt+1,dt+n+1,cmp1);for(int i=1;i<=n;++i){int j=i;if(rnk[dt[j+1].i]==rnk[dt[j].i])++j;if(i!=j)V.push_back(upd(2,dt[i].y,rnk[dt[i].i],1)),V.push_back(upd(2,dt[j].y,rnk[dt[j].i],-1));}sort(V.begin(),V.end());for(upd u:V)if(u.t==2)update(u.l,u.r);else ans+=query(u.r-1)-query(u.l);printf("%lld",ans+n);
}

http://www.ppmy.cn/news/244196.html

相关文章

NOI / 2.5基本算法之搜索-1818:红与黑

总时间限制: 1000ms 内存限制: 65536kB 描述 有一间长方形的房子&#xff0c;地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上&#xff0c;只能向相邻的黑色瓷砖移动。请写一个程序&#xff0c;计算你总共能够到达多少块黑色的瓷砖。 输…

Android adb shell后面可用的常用命令详细列举

adb shell 后面可以跟的常见命令有如下&#xff1a; am app_process backup bootanimation coloradjust dpm idmap input media requestsync settings svc uiautomator appops appwidget bmgr bu content hid ime interrupter pm screencap sm telecom wm dumpsys logcat getpr…

f4v文件解析

经过几天日夜,对照 flv_video_file_format_spec_v10_1.pdf,用C写了个f4v文件分析工具。也适应mp4文件分析。 原始文件为 sky.f4v 由ffmpeg生成(ffmpeg -i sky.mov sky.f4v) 链接: https://pan.baidu.com/s/1asrSPJZq1Zv4zQaYqgDsRg 密码: frec flv.exe (./flv sky.f4v)…

v-if,v-else-if, v-else的实际使用

需求是医疗水平&#xff0c;价格水平&#xff0c;服务态度分值都为0-10分&#xff0c;1-4分是红色&#xff0c;5-7分是黄色&#xff0c;8-10分是绿色&#xff0c;数据均从后台请求过来的。 一开始想的是通过Vue中ref属性&#xff0c;可以获取到当前元素&#xff0c;在数据请求…

我在公司彻夜加班,老板居然做出这种事.....

讲道理&#xff0c;我的学历远达不到BAT等名企大厂的要求&#xff0c;去不了好公司我认了&#xff0c;大专毕业的我在找工作的时候发现留给自己的机会并不多&#xff0c;最后去了一家不知名的小公司。入职后才发现这家公司其实就是个外包公司&#xff0c;里面的业务部门和制度相…

智慧加油站解决方案,提高加油区和卸油区的安全性和效率

英码科技智慧加油站解决方案是一个综合应用了AI智能算法的视觉分析方案&#xff0c;旨在提高加油区和卸油区的安全性和效率。 加油区算法&#xff1a; 吸烟检测&#xff1a;通过AI算法分析视频流&#xff0c;检测是否有人在加油区域吸烟&#xff0c;以防止火灾风险。 打电话…

Java中Object类常用的11个方法

Java中Object类常用的11个方法 先看下 Object 的类结构&#xff08;快捷键&#xff1a;alt7&#xff09;&#xff1a; 1. getClass 方法&#xff08;获取类的class对象。&#xff09; public final native Class<?> getClass();final 方法、获取对象的运行时 class …

速度无敌

无奈blogspot总是受到长城的关心&#xff0c;无法安心写东西。要么写不了&#xff0c;要么看不到&#xff0c;无奈无语。 还要重拾cnblogs的博客&#xff0c;混杂在各位技术员里面的博客感觉还是很好地&#xff0c;在下在这里滥竽充数一下。忘各位程序员大大不要计较我这个普通…