BZOJ4989 [Usaco2017 Feb]Why Did the Cow Cross the Road 树状数组 逆序对

欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ4989


题意概括

  一条马路的两边分别对应的序列A、B,长度为n,两序列为1到n的全排列。当Ai=Bj时,两边之间会连一条边。你可以选择序列A或序列B进行旋转(只能使队尾或队头位置上的数字变成队头或队尾上的数字)任意K(0<=K<n)步,如123,可以变成 231 或 312。求旋转后,最少的边的交叉数。


题解

  两个都可以转,那么我们只需要分别转动两个并统计即可。
  旋转一个,那么我们只需要统计逆序对就可以了。对于任意一个情况,逆序对可以nlogn求出,但是如何统计这n种情况呢。我们发现,从一种情况转到另一种情况,改变的仅是与动的哪一个数字有关的,那么只需要加加减减就可以转移了。


代码

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=100000+5;
int n,a[N],b[N],c[N],A[N],B[N];
LL tot,ans;
LL min(LL a,LL b){
	return a<b?a:b;
}
int lowbit(int x){
	return x&-x;
}
void add(int x,int d){
	for (;x<=n;x+=lowbit(x))
		c[x]+=d;
}
LL sum(int x){
	int ans=0;
	for (;x>0;x-=lowbit(x))
		ans+=c[x];
	return ans;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),A[i]=a[i];
	for (int i=1;i<=n;i++)
		scanf("%d",&b[i]),B[i]=b[i];
	for (int i=1;i<=n;i++)
		c[b[i]]=i;
	for (int i=1;i<=n;i++)
		a[i]=c[a[i]];
	memset(c,0,sizeof c);
	tot=0;
	for (int i=n;i>=1;i--){
		tot+=sum(a[i]-1);
		add(a[i],1);
	}
	ans=tot;
	for (int i=n;i>=1;i--){
		tot=tot-(LL)(n-a[i])+(LL)(a[i]-1);
		ans=min(ans,tot);
	}
	for (int i=1;i<=n;i++)
		a[i]=B[i];
	for (int i=1;i<=n;i++)
		b[i]=A[i];
	for (int i=1;i<=n;i++)
		c[b[i]]=i;
	for (int i=1;i<=n;i++)
		a[i]=c[a[i]];
	memset(c,0,sizeof c);
	tot=0;
	for (int i=n;i>=1;i--){
		tot+=sum(a[i]-1);
		add(a[i],1);
	}
	for (int i=n;i>=1;i--){
		tot=tot-(LL)(n-a[i])+(LL)(a[i]-1);
		ans=min(ans,tot);
	}
	printf("%lld",ans);
	return 0;
}

  

时间: 2025-01-04 20:53:04

BZOJ4989 [Usaco2017 Feb]Why Did the Cow Cross the Road 树状数组 逆序对的相关文章

[BZOJ4989] [Usaco2017 Feb]Why Did the Cow Cross the Road(树状数组)

传送门 发现就是逆序对 可以树状数组求出 对于旋转操作,把一个序列最后面一个数移到开头,假设另一个序列的这个数在位置x,那么对答案的贡献 - (n - x) + (x - 1) #include <cstdio> #include <cstring> #include <iostream> #define N 200011 #define LL long long using namespace std; int n; int a[N], b[N], pos1[N],

HDU - 2838 Cow Sorting (树状数组 + 逆序对)

HDU - 2838 Cow Sorting Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" lev

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

欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4994 题意概括 给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数. n<=100000(这个数据范围是我凑出来的,但是我没试过更小的范围,BZOJ上没写数据范围(截止2017-08-24)) 题解 水题,开一个树状数组在线解决. 比如我们顺着扫过去,当到达一个 bj 时,我们求满足条件的 ai,bi 个数,其实就

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

传送门 1.每个数的左右位置预处理出来,按照左端点排序,因为左端点是从小到大的,我们只需要知道每条线段包含了多少个前面线段的右端点即可,可以用树状数组 2.如果 ai < bj < bi, 也就是说在两个i之间只有一个j那么对答案的贡献为1,所以可以用树状数组,当第一次出现一个数的时候,那个位置+1,当第二次出现的时候,第一次出现的位置再-1,也就是把它对答案的贡献去掉,同样是树状数组统计答案 #include <cstdio> #include <iostream>

【bzoj4994】[Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组

题目描述 给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数 样例输入 4 3 2 4 4 1 3 2 1 样例输出 3 题解 树状数组 WH说是CDQ分治直接把我整蒙了... 把所有数按照第一次出现位置从小到大排序,然后扫一遍.此时一定是满足$a_j>a_i$的. 那么只需要求出$(a_j,b_j)$中以前出现过的$b_i$的数目.使用树状数组维护即可. 时间复杂度$O(n\log n)$ #include &l

【POJ 3167】Cow Patterns (KMP+树状数组)

Cow Patterns Description A particular subgroup of K (1 <= K <= 25,000) of Farmer John's cows likes to make trouble. When placed in a line, these troublemakers stand together in a particular order. In order to locate these troublemakers, FJ has lined

[Usaco2017 Feb]Why Did the Cow Cross the RoadII

[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4993 [算法] 动态规划 转移类似于求LCS [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 1010 int n; int a[MAXN] , b[MAXN]; int f[MAXN][MAXN]; template <typename T> inline void chkmax(T &a

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

Why Did the Cow Cross the Road III 时间限制: 1 Sec  内存限制: 128 MB提交: 65  解决: 28[提交][状态][讨论版] 题目描述 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

洛谷 P3660 [USACO17FEB]Why Did the Cow Cross the Road III G(树状数组)

题目背景 给定长度为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 morn