斜率小于0的连线数量 51NOD
来源:互联网 发布:棋牌室软件 编辑:程序博客网 时间:2024/06/05 18:47
点击打开链接
题目要求再一共 n*(n-1)/2条连线中找出所有斜率小于零的
其实就是累加每个点右下方有多少个点 或者累加每个点左上方有多少个点 这样就转换成了求逆序对的问题
注意处理一下 斜率为零或不存在的情况就好
这里抛开题目 只谈求一个排列的逆序对
在线性代数中 我们有三种方法求一个排列的逆序对
1 从左到右 看每一个元素左边有多少比它大的
2 从右到左 看每一个元素右边有多少比它小的
3 从小到大 看每个数的左边有多少比它大的 右边有多少比它小的 然后划去这个数 即划去法
我们采用第一种方法
对于一个排列 我们用a[n]数组保存 再用b[n]数组保存升序排序后的a[n] 然后基于b[n]建立线段树(值初始化为0)
遍历a[n] 对于每一个元素a[i] 先找到其在b[n]中的位置 p (如下代码所示建映射表 用map比较慢) 查询 [p n] 区间内已经有多少个数是之前已经遍历过的 累加这个值 然后更新p位置已来过即可
这样做的意义就是 看a[1]到a[i-1]中有多少个元素比a[i]要大
#include <bits/stdc++.h>using namespace std;#define ll long longstruct node1{ int x; int y; int id;};struct node2{ int l; int r; ll val;};node1 point[50010];node2 tree[200010];ll num[50010];int pos[50010];int n;int cmp1(node1 n1,node1 n2);int cmp2(node1 n1,node1 n2);void build(int l,int r,int cur);ll query(int pl,int pr,int cur);void update(int tar,int cur);void pushup(int cur);int main(){ ll sum; int i,j,cnt; num[0]=0; for(i=1;i<=50000;i++) { num[i]=num[i-1]+i; } while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) { scanf("%d%d",&point[i].x,&point[i].y); } point[0].x=-1,point[0].y=-1; sum=0,cnt=0; sort(point+1,point+n+1,cmp1); for(i=1;i<=n;i++) { if(point[i].x==point[i-1].x) { cnt++; } else { sum-=num[cnt]; cnt=0; } point[i].id=i; } sum-=num[cnt]; cnt=0; sort(point+1,point+n+1,cmp2); for(i=1;i<=n;i++) { if(point[i].y==point[i-1].y) { cnt++; } else { sum-=num[cnt]; cnt=0; } pos[point[i].id]=i; } sum-=num[cnt]; build(1,n,1); for(i=1;i<=n;i++) { sum+=query(pos[i],n,1); update(pos[i],1); } printf("%lld\n",sum); } return 0;}int cmp1(node1 n1,node1 n2){ if(n1.x==n2.x) { return n1.y>n2.y; } else { return n1.x<n2.x; }}int cmp2(node1 n1,node1 n2){ if(n1.y==n2.y) { return n1.x>n2.x; } else { return n1.y<n2.y; }}void build(int l,int r,int cur){ int m; tree[cur].l=l; tree[cur].r=r; tree[cur].val=0; if(l==r) return; m=(l+r)/2; build(l,m,cur*2); build(m+1,r,cur*2+1); return;}ll query(int pl,int pr,int cur){ ll ans; if(pl<=tree[cur].l&&tree[cur].r<=pr) { return tree[cur].val; } if(tree[cur].l==tree[cur].r) { return 0; } ans=0; if(pl<=tree[cur*2].r) ans+=query(pl,pr,cur*2); if(pr>=tree[cur*2+1].l) ans+=query(pl,pr,cur*2+1); return ans;}void update(int tar,int cur){ if(tree[cur].l==tree[cur].r) { tree[cur].val=1; return; } if(tar<=tree[cur*2].r) update(tar,cur*2); else update(tar,cur*2+1); pushup(cur); return;}void pushup(int cur){ tree[cur].val=tree[cur*2].val+tree[cur*2+1].val; return;}
阅读全文
1 0
- 51nod 1107 斜率小于0的连线数量
- 斜率小于0的连线数量 51Nod
- 51nod 1107 斜率小于0的连线数量
- 斜率小于0的连线数量 51NOD
- 51 nod 1107 斜率小于0的连线数量
- 51Nod 1107 斜率小于0的连线数量
- 51nod 1107 斜率小于0的连线的数量 (逆序数)
- 51nod 1107 斜率小于0的连线数量 (树状数组+离线化)
- 51nod-1107 斜率小于0的连线数量(逆序数+离散化)
- 51Nod-1107-斜率小于0的连线数量
- 51nod oj 1107 斜率小于0的连线数量 【类逆序数】
- 51NOD 1107 斜率小于0的连线数量 坐标离散化+树状数组
- 51nod-斜率小于0的连线数量(树状数组+离散化)
- 51nod 1107 斜率小于0的连线数量(逆序数)
- 51nod 1107 斜率小于0的连线数量 树状数组
- 1107 斜率小于0的连线数量
- 斜率小于0的连线数量-归并排序
- 1107 斜率小于0的连线数量 求逆序对
- Windows平台下内存泄露分析:WinDbg
- 仿开眼APP kotlin
- SSH三者的作用(JavaWeb)
- mfc 内嵌cef浏览器开发
- ActiveMQ的基本使用
- 斜率小于0的连线数量 51NOD
- linux命令--grep
- (二)索引规约
- 10月9日AssetBundle学习笔记
- Python 字符串匹配(match)
- [练习]背包DP 竞赛得分
- 点击新闻条目显示更详细的信息
- HashMap分析
- ubuntu14.04 安装opencv 2.13