zoukankan      html  css  js  c++  java
  • [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], pos2[N];
    LL c[N], ans = 1ll * N * N;
    
    inline int read()
    {
    	int x = 0, f = 1;
    	char ch = getchar();
    	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    	return x * f;
    }
    
    inline void add(int x)
    {
    	for(; x <= n; x += x & -x) c[x]++;
    }
    
    inline LL query(int x)
    {
    	LL ret = 0;
    	for(; x; x -= x & -x) ret += c[x];
    	return ret;
    }
    
    inline void solve()
    {
    	int i, x;
    	LL sum = 0;
    	memset(c, 0, sizeof(c));
    	for(i = 1; i <= n; i++) pos1[a[i]] = i;
    	for(i = 1; i <= n; i++) pos2[b[i]] = i;
    	for(i = 1; i <= n; i++)
    	{
    		x = pos1[b[i]];
    		sum += (LL)i - 1 - query(x);
    		add(x);
    	}
    	ans = min(ans, sum);
    	for(i = n; i > 1; i--)
    	{
    		x = pos2[a[i]];
    		sum -= n - x;
    		sum += x - 1;
    		ans = min(ans, sum);
    	}
    }
    
    int main()
    {
    	int i;
    	n = read();
    	for(i = 1; i <= n; i++) a[i] = read();
    	for(i = 1; i <= n; i++) b[i] = read();
    	solve();
    	swap(a, b);
    	solve();
    	printf("%lld
    ", ans);
    	return 0;
    }
    

      

  • 相关阅读:
    L2-011 玩转二叉树 二叉树
    L2-010 排座位 并查集
    L2-009 抢红包
    VS 编译报错:意外的字符
    关于js的类型转换
    github相关操作总结
    关于时间的相关处理
    uniapp实现简单的动画效果(不使用dom操作)
    uniapp选择日期
    vue使用音频组件
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7569788.html
Copyright © 2011-2022 走看看