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个点 分析 ...
随机推荐
- Xcode文件被锁定:The file ".xcodeproj" could not be unlocked
同事从svn上面checkout项目到本地,通过xcode打开的时候提示的这个问题. The file "xcodeproj" could not be unlocked. Cou ...
- 8 -- 深入使用Spring -- 3...1 Resource实现类
8.3.1 Resource实现类 Resource接口是Spring资源访问的接口,具体的资源访问由该接口的实现类完成. Spring提供的Resource接口的实现类: ⊙ UrlResource ...
- 诡异的DataTime.Now.ToString()
昨天晚上调程序的时候在服务器上出现这种问题 DataTime.Now.ToString("yyyy-MM-dd HH:mm:ss") 居然出现了2014-8-14 8:nn:14: ...
- Echarts调整图表上下左右的间距,Echarts调整柱状图左右的间距
Echarts调整图表上下左右的间距,Echarts调整柱状图左右的间距 >>>>>>>>>>>>>>>> ...
- 文件完整性hash验证demo(python脚本)
一个简单的文件完整性hash验证脚本 #!/usr/bin/env python # -*- coding: utf- -*- import os import hashlib import json ...
- Redis存读取数据
这一节演示下载.NET中怎样使用Redis存储数据.在.net中比较常用的客户端类库是ServiceStack,看下通过servicestack怎样存储数据. DLL下载:https://github ...
- iOS开发-iOS7禁用手势返回
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // 禁用 iOS7 返回手势 if ([self.nav ...
- JSP基本用法(一)运行机制和语法
一.概述 JSP是一种建立在Servlet规范功能上的动态网页技术,在网页文件中嵌入Java代码和JSP标记用于产生动态内容. 本文简单介绍JSP的运行机制和JSP的语法. 二.JSP的运行机制 JS ...
- JS使用中碰到的一些问题
settimeout: 1.setTimeout(function () {//这个则会在1秒后进行弹出1 alert(1); }, 1000); 2.setTimeout(alert(1), 100 ...
- WP8.1学习系列(第二十章)——添加控件和处理事件
先决条件 添加控件 设置控件的名称 设置控件属性 创建事件处理程序 新控件 总结 相关主题 通过使用如按钮.文本框和组合框等控件,你可以创建应用的 UI. 下面将显示如何将控件添加到应用.处理控件时, ...