POJ 3067 - Japan - [归并排序/树状数组(BIT)求逆序对]
Time Limit: 1000MS Memory Limit: 65536K
Description
Input
Output
Test case (case number): (number of crossings)
Sample Input
1
3 4 4
1 4
2 3
3 2
3 1
Sample Output
Test case 1: 5
题意:
左边一排 1 ~ n 的城市,右边一排 1 ~ m 的城市,都从上到下依次对应。接着给你一些城市对,表示城市这两个城市相连;
最后问你一共有多少个交叉,其中处于城市处的交叉不算,并且每个位置最多只能有一个交叉。
题解:
抽象来说就是求逆序对的问题,虽然放在树状数组的章节里,但不一定要用树状数组,归并排序也可以……
还有关于k的范围……起点最多1000个,终点最多1000个,那么连线最多显然是1000*1000个啊……哪里坑了……
#include<cstdio>
#include<algorithm>
#define MAX 1000*1000+3
using namespace std;
struct Road{
int u,v;
}road[MAX],tmp[MAX];
int n,m,k;
long long cnt;
bool cmp(Road a,Road b)
{
if(a.u==b.u) return a.v<b.v;
else return a.u<b.u;
}
void Merge(int l,int m,int r)
{
int i = l;
int j = m + ;
int k = l;
while(i <= m && j <= r)
{
if(road[i].v > road[j].v)
{
tmp[k++] = road[j++];
cnt += m - i + ;
}
else
{
tmp[k++] = road[i++];
}
}
while(i <= m) tmp[k++] = road[i++];
while(j <= r) tmp[k++] = road[j++];
for(int i=l;i<=r;i++) road[i] = tmp[i];
}
void Merge_sort(int l,int r)
{
if(l < r)
{
int m = (l + r) >> ;
Merge_sort(l,m);
Merge_sort(m+,r);
Merge(l,m,r);
}
}
int main()
{
int t;
scanf("%d",&t);
for(int kase=;kase<=t;kase++)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=k;i++) scanf("%d%d",&road[i].u,&road[i].v);
sort(road+,road+k+,cmp);
cnt=;
Merge_sort(,k);
printf("Test case %d: %I64d\n",kase,cnt);
}
}
不过既然是在BIT这节里的题,那总归也要用BIT做一下……
#include<cstdio>
#include<algorithm>
#define MAXN 1000*1000+3
using namespace std;
int n,m,k;
struct Road{
int u,v;
}road[MAXN];
bool cmp(Road a,Road b)
{
if(a.u==b.u) return a.v<b.v;
else return a.u<b.u;
}
//BIT - 单点增加,区间查询 - st
struct _BIT{
int N,C[MAXN];
int lowbit(int x){return x&(-x);}
void init(int n)//初始化共有n个点
{
N=n;
for(int i=;i<=N;i++) C[i]=;
}
void add(int pos,int val)//在pos点加上val
{
while(pos<=N)
{
C[pos]+=val;
pos+=lowbit(pos);
}
}
int sum(int pos)//查询1~pos点的和
{
int ret=;
while(pos>)
{
ret+=C[pos];
pos-=lowbit(pos);
}
return ret;
}
}BIT;
//BIT - 单点增加,区间查询 - ed
int main()
{
int t;
scanf("%d",&t);
for(int kase=;kase<=t;kase++)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=k;i++) scanf("%d%d",&road[i].u,&road[i].v);
sort(road+,road+k+,cmp); long long cnt=;
BIT.init(m);
for(int i=;i<=k;i++)
{
BIT.add(road[i].v,);//road[i].v出现一次,加上
cnt+=BIT.sum(m)-BIT.sum(road[i].v);//计算出在目前情况下,有多少个比road[i].v大的数出现过
}
printf("Test case %d: %I64d\n",kase,cnt);
}
}
当然啦,事实告诉了我们,用BIT不是没有道理的,各方面都比归并排序求逆序对要好一些。
更多树状数组模板请走传送门:树状数组进阶。
POJ 3067 - Japan - [归并排序/树状数组(BIT)求逆序对]的更多相关文章
- POJ 3067 Japan 【树状数组经典】
题目链接:POJ 3067 Japan Japan Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 32076 Accep ...
- poj 3067 Japan(树状数组求逆序数)
链接:http://poj.org/problem?id=3067 题意:左边有n个城市,右边有m个城市,建k条道路,问有这k条道路中有多少个交点. 分析:将城市按x和y从小到大排序,对于每条道路,求 ...
- POJ 3067 Japan(树状数组)
Japan Time Limit: 10 ...
- poj 3067 Japan 【树状数组】
<题目链接> 题目大意: 有两个点集,这两个点集从上至下分别从1~n,1~m编号,现在给出n组数据,(x,y),表示左边点集编号为x的点与右边点集编号为y的点相连,现在要求计算这些线段的交 ...
- POJ 3067 Japan 【 树状数组 】
题意:左边有n个城市,右边有m个城市,现在修k条路,问会形成多少个交点 先按照x从小到大排,x相同的话,则按照y从小到大排,然后对于每一个y统计前面有多少个y比它大,它们就一定会相交 另外要用long ...
- POJ 2299 树状数组+离散化求逆序对
给出一个序列 相邻的两个数可以进行交换 问最少交换多少次可以让他变成递增序列 每个数都是独一无二的 其实就是问冒泡往后 最多多少次 但是按普通冒泡记录次数一定会超时 冒泡记录次数的本质是每个数的逆序数 ...
- POJ 2299 Ultra-QuickSort (树状数组+离散化 求逆序数)
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a seque ...
- HDU 1394 树状数组+离散化求逆序数
对于求逆序数问题,学会去利用树状数组进行转换求解方式,是很必要的. 一般来说我们求解逆序数,是在给定一串序列里,用循环的方式找到每一个数之前有多少个比它大的数,算法的时间复杂度为o(n2). 那么我们 ...
- POJ 3067 原来是树状数组--真的涨姿势
题意:计划在东边的城市和西边的城市中建路,东边的点从1.....n,西边的点从1......m,求这些点连起来后有多少个交叉. PS:这个题目没有任何思路,没想到是树状数组.... 交叉出5个点 分析 ...
随机推荐
- Linux+Redis实战教程_day01_Linux介绍与安装
1.Linux介绍(了解) 1.1.Linux和Windows的区别 Linux是一款操作系统.正规开发 服务器项目部署都是放在Linux操作系统上. Windows一款操作系统,民用操作系统.娱乐. ...
- 8 -- 深入使用Spring -- 4...5 AOP代理:基于注解的“零配置”方式
8.4.5 基于注解的“零配置”方式 AspectJ允许使用注解定义切面.切入点和增强处理,而Spring框架则可识别并根据这些注解来生成AOP代理.Spring只是使用了和AspectJ 5 一样的 ...
- chm只看到目录,看不到内容解决办法
鼠标左键->属性->解除锁定->搞定!
- Swift - 3.0 去掉 C 风格循环
Swift 3.0 版本去掉了沿用已久的 C 风格循环语法, 又是向现代开发语言的一次迈进, 咱们就来看看没了 C 风格循环我们还有什么选择 C 风格循环 关于 C 风格循环, 不我们过多介绍了, 就 ...
- cp自动创建层级结构的例子
一个拷贝命令的技巧,不仅拷贝文件,而且拷贝目录结构.记录下来. *拷贝的时候,自动创建参数中源文件的路径:#cp --parents parentdir1/parentdir2/sourcefile ...
- jQuery Easing 动画效果扩展--使用Easing插件,让你的动画更具美感。
jQuery Easing 是一款比较老的jQuery插件,在很多网站都有应用,尤其是在一些页面滚动.幻灯片切换等场景应用比较多.它非常小巧,且有多种动画方案供选择,使用简单,而且免费. 引入Eas ...
- 虚拟机上的centos连不了外网,吧原来的配置信息改成如下就行(删除了一些多余的信息,变化:原来的ONBOOT的值是no)
DEVICE=eth1BOOTPROTO=dhcpHWADDR=08:00:27:67:be:98ONBOOT=yes
- Matlab练习——素数查找
输入数字,0结束,判断输入的数字中的素数 clc; %清空命令行窗口的数据 clear; %清除工作空间的变量 k = ; n = ; %素数的个数 zzs(k) = input('请输入正整数: ' ...
- linux添加静态路由
1.使用route命令,查看本机路由直接输入route回车即可.route 命令参数: add 增加路由 del 删除路由 -net 设置到某个网段的路由 -host 设置到 ...
- nginx介绍和安装
1.nginx的介绍 1.1 nginx的优势 1) 作为Web服务器,Nginx处理静态文件.索引文件,自动索引的效率非常高. 2) 作为代理服务器,Nginx可以实现无缓存的反向代理加速,提高网站 ...