博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 3067 Japan (树状数组 && 控制变量)
阅读量:4317 次
发布时间:2019-06-06

本文共 1566 字,大约阅读时间需要 5 分钟。

题意: 西海岸和东海岸有分别有n (1~n)个和m (1~m)个城市, 两个海岸的城市之间有k条公路连通, 公路会相交, 现在给出城市和公路的信息问你由这些公路组成的复杂交通有多少个交点 (如果两个条公路的起点或者终点相同那这两点不算做相交)

 

分析: 这里公路信息用(x, y)二元组来表示西海岸的x城市与东海岸的y城市相连, 首先自然想到给k个公路的信息按x或y排个序, 否则变量太乱不助于思考!先设想按x升序排序且先不管x相等的情况, 如果x是升序的, 那我在考虑第i条公路的时候是不是只要关心yi值是否比之前所有的点的y值大就行了, 如果比所有之前的点的y值都大, 则之前没有线yi相交, 否则有之前有j个比它大的则就将多产生j个交点。这样去控制变量的计算方法可以自然与求逆序对联系到一起, 细想如果我先按x升序再按y升序, 那按照上面所述的方法, 是不是只要求出此时y数列的逆序对个数即可?那如果x相等怎么办呢?很显然, 如果x相等, 由于题目说 (如果两个条公路的起点或者终点相同那这两点不算做相交) , 那这两条线必定不能产生交点, 即不能在在线计算的过程中产生逆序对, 那只要先处理y比较小的即可, 也就是为什么x相等就按y从小到大排序的理由。既然是求逆序对, 便用到树状数组了!

 

瞎想: 可以发现在用树状数组解决问题时候, 应该多去想如何控制变量或者使变量单一(排序或者....其他), 或者将其变成求逆序数的经典模型, 或者将区间(一般是两端点)转画成直角坐标系里的x,y等方法来寻求规律!

瞎搞: 当时想偷偷懒, 用个set< pair<int, int> >来存储, 的确也能做到, 不过TLE的我眼泪掉下来!还有就是最后的ans是交点个数, 可以很大, 我一开始缺用了int, 最后才发现啊!

 

#include
#include
#include
#include
#include
#include
#define LL long long#define lowbit(i) (i&(-i))using namespace std;int c[1001], n, k, m;inline void add(int i, int val){ while(i<=m){ //由于是求y序列所以这里上限是m c[i] += val; i += lowbit(i); }}LL sum(int i){ LL ans = 0; while(i>0){ ans += c[i]; i -= lowbit(i); } return ans;}typedef struct stru{ int x, y;}A;A arr[10000000];bool cmp(const A fir, const A sec){ if(fir.x == sec.x) return fir.y < sec.y; return fir.x < sec.x;}int main(void){ int nCase; scanf("%d", &nCase); for(int t=1; t<=nCase; t++){ memset(c, 0, sizeof(c)); scanf("%d%d%d", &n, &m, &k); for(int i=0; i
View Code

 

转载于:https://www.cnblogs.com/LiHior/p/6914406.html

你可能感兴趣的文章
代码示例_进程
查看>>
Java中关键词之this,super的使用
查看>>
学习进度
查看>>
“此人不存在”
查看>>
github.com加速节点
查看>>
解密zend-PHP凤凰源码程序
查看>>
python3 序列分片记录
查看>>
Atitit.git的存储结构and 追踪
查看>>
atitit 读书与获取知识资料的attilax的总结.docx
查看>>
B站 React教程笔记day2(3)React-Redux
查看>>
找了一个api管理工具
查看>>
Part 2 - Fundamentals(4-10)
查看>>
使用Postmark测试后端存储性能
查看>>
NSTextView 文字链接的定制化
查看>>
第五天站立会议内容
查看>>
CentOs7安装rabbitmq
查看>>
(转))iOS App上架AppStore 会遇到的坑
查看>>
解决vmware与主机无法连通的问题
查看>>
做好产品
查看>>
项目管理经验
查看>>