题目背景

给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数

题目描述

The layout of Farmer John's farm is quite peculiar, with a large circular road running around the perimeter of the main field on which his cows graze during the day. Every morning, the cows cross this road on their way towards the field, and every evening they all cross again as they leave the field and return to the barn.

As we know, cows are creatures of habit, and they each cross the road the same way every day. Each cow crosses into the field at a different point from where she crosses out of the field, and all of these crossing points are distinct from each-other. Farmer John owns NN cows, conveniently identified with the integer IDs 1 \ldots N1…N, so there are precisely 2N2N crossing points around the road. Farmer John records these crossing points concisely by scanning around the circle clockwise, writing down the ID of the cow for each crossing point, ultimately forming a sequence with 2N2N numbers in which each number appears exactly twice. He does not record which crossing points are entry points and which are exit points.

Looking at his map of crossing points, Farmer John is curious how many times various pairs of cows might cross paths during the day. He calls a pair of cows (a,b)(a,b) a "crossing" pair if cow aa's path from entry to exit must cross cow bb's path from entry to exit. Please help Farmer John count the total number of crossing pairs.

输入输出格式

输入格式:

The first line of input contains NN (1 \leq N \leq 50,0001≤N≤50,000), and the next 2N2N lines describe the cow IDs for the sequence of entry and exit points around the field.

输出格式:

Please print the total number of crossing pairs.

输入输出样例

输入样例#1:

4
3
2
4
4
1
3
2
1
输出样例#1:

3

 解:这题用树状数组就可以做出来了,难度一般。先预处理好所有的数字的两个位置。

  我们可以对每段区间左边和右边分别进行求和,并取最小值。

  进行累加就可以得到答案了。   嗯。。。类似求逆序对的方法

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define man 50010
#define lo(x) (x&(-x))
#define read(x) scanf("%d",&x)
/*TEST*/
int n;
struct node
{ int x,y;}e[man<<2];
/*B_TREE*/
int c[man<<2];
inline void update(int x,int val)
{ while(x<=2*n)
{ c[x]+=val;
x+=lo(x);
}
return ;
}
inline int query(int x)
{ int ans=0;
while(x>0)
{ ans+=c[x];
x-=lo(x);
}
return ans;
}
inline int calc(int x,int y)
{ int l=query(x);
int r=query(y);
r=r-l;
return min(l,r);//从1位置到左端点,从左端点位置+1到右端点
}
/*SORT*/
inline int cmp(node a,node b)
{ return a.x<b.x;}
int main()
{ read(n);
for(int i=1;i<=2*n;i++)
{ int tmp;read(tmp);
if(e[tmp].x>0)
e[tmp].y=i;
else e[tmp].x=i;
}
sort(e+1,e+1+n,cmp);
int ans=0;
for(int i=1;i<=n;i++)
{ ans+=calc(e[i].x,e[i].y);
update(e[i].x,1);
update(e[i].y,1);
}
printf("%d\n",ans);
return 0;
}

  

洛谷 P3660 [USACO17FEB]Why Did the Cow Cross the Road III G(树状数组)的更多相关文章

  1. [USACO17FEB]Why Did the Cow Cross the Road III G (树状数组,排序)

    题目链接 Solution 二维偏序问题. 现将所有点按照左端点排序,如此以来从左至右便满足了 \(a_i<a_j\) . 接下来对于任意一个点 \(j\) ,其之前的所有节点都满足 \(a_i ...

  2. 【题解】洛谷P3660 [USACO17FEB]Why Did the Cow Cross the Road III

    题目地址 又是一道奶牛题 从左到右扫描,树状数组维护[左端点出现而右端点未出现]的数字的个数.记录每个数字第一次出现的位置. 若是第二次出现,那么删除第一次的影响. #include <cstd ...

  3. 洛谷 P3663 [USACO17FEB]Why Did the Cow Cross the Road III S

    P3663 [USACO17FEB]Why Did the Cow Cross the Road III S 题目描述 Why did the cow cross the road? Well, on ...

  4. Why Did the Cow Cross the Road III(树状数组)

    Why Did the Cow Cross the Road III 时间限制: 1 Sec  内存限制: 128 MB提交: 65  解决: 28[提交][状态][讨论版] 题目描述 The lay ...

  5. 洛谷 P3659 [USACO17FEB]Why Did the Cow Cross the Road I G

    //神题目(题目一开始就理解错了)... 题目描述 Why did the cow cross the road? Well, one reason is that Farmer John's far ...

  6. [USACO17FEB] Why Did the Cow Cross the Road I P (树状数组求逆序对 易错题)

    题目大意:给你两个序列,可以序列进行若干次旋转操作(两个都可以转),对两个序列相同权值的地方连边,求最少的交点数 记录某个值在第一个序列的位置,再记录第二个序列中某个值 在第一个序列出现的位置 ,求逆 ...

  7. P3660 [USACO17FEB]Why Did the Cow Cross the Road III G

    Link 题意: 给定长度为 \(2N\) 的序列,\(1~N\) 各处现过 \(2\) 次,i第一次出现位置记为\(ai\),第二次记为\(bi\),求满足\(ai<aj<bi<b ...

  8. BZOJ 4990 [USACO17FEB] Why Did the Cow Cross the Road II P (树状数组优化DP)

    题目大意:给你两个序列,你可以两个序列的点之间连边 要求:1.只能在点权差值不大于4的点之间连边 2.边和边不能相交 3.每个点只能连一次 设表示第一个序列进行到 i,第二个序列进行到 j,最多连的边 ...

  9. [BZOJ4994] [Usaco2017 Feb]Why Did the Cow Cross the Road III(树状数组)

    传送门 1.每个数的左右位置预处理出来,按照左端点排序,因为左端点是从小到大的,我们只需要知道每条线段包含了多少个前面线段的右端点即可,可以用树状数组 2.如果 ai < bj < bi, ...

随机推荐

  1. ZetCode PyQt4 tutorial layout management

    !/usr/bin/python -*- coding: utf-8 -*- """ ZetCode PyQt4 tutorial This example shows ...

  2. jenkins配置email

    # 系统设置 # Jenkins Location # 邮件通知 # 高级 # Failed to send out e-mail 勾选“使用SSL协议” SMTP端口改为465 密码使用授权码,不能 ...

  3. /etc/fstab和/etc/mtab

    一./etc/fstab和/etc/mtab的区别 1./etc/fstab /etc/fstab是开机自动挂载的配置文件,在开机时起作用.相当于启动linux的时候,自动使用检查分区的fsck命令和 ...

  4. string学习

    来自:http://www.cnblogs.com/kkgreen/archive/2011/08/24/2151450.html 0,new是创了两个对象,一个在堆,一个在常量池 1,变量+字符串= ...

  5. git Permissions 0777 for '/home/xxx/.ssh/id_rsa' are too open.

    使用 git 时出现下面的问题,原因是 git 公钥的权限被修改了. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WAR ...

  6. 02 - Unit011:Spring AOP

    Spring AOP 面向切面(儿)编程(横切编程) Spring 核心功能之一 Spring 利用AspectJ 实现. 底层是利用 反射的动态代理机制实现的 其好处: 在不改变原有功能情况下, 为 ...

  7. java用double和float进行小数计算精度不准确

    java用double和float进行小数计算精度不准确 大多数情况下,使用double和float计算的结果是准确的,但是在一些精度要求很高的系统中或者已知的小数计算得到的结果会不准确,这种问题是非 ...

  8. 【free() invalid next size】谨慎地在C++的类中存储指针来方便访问其他节点

    “我跟你们说,你们知道STL容器,vector/string/deque等等,都有个reserve方法吗?你们一个个地push_back,嫌C++比C慢,怪谁?” “要像我这样,预先分配足够大的空间, ...

  9. H5页面获取openid,完成支付公众号(未关注公众号)支付

    一.页面授权 // 进入页面获取权限code function initAuthorizeCode() { var appid = $("#appid").val();//公众号a ...

  10. 黄聪:Microsoft office 2013版下载、安装及破解工具下载破解教程(Windows Toolkit)

    Microsoft Office 2013(Office 15)是微软的新一代Office办公软件,全面采用Metro界面.Microsoft Office 2013官方下载(Office2013专业 ...