zoukankan      html  css  js  c++  java
  • 【Luogu P4375】[USACO18OPEN]Out of Sorts G

    链接:

    洛谷

    博客园

    题目大意:

    有一段代码:

    sorted = false
    while (not sorted):
       sorted = true
       moo
       for i = 0 to N-2:
          if A[i+1] < A[i]:
             swap A[i], A[i+1]
       for i = N-2 downto 0:
          if A[i+1] < A[i]:
             swap A[i], A[i+1]
       for i = 0 to N-2:
          if A[i+1] < A[i]:
             sorted = false
    

    让你求这段代码里的 moo 会运行多少次。

    正文:

    这道题的思路很妙。首先单独看第一个 for 循环,你会发现这个操作其实等价于将若干个数 (a_i) 移到一个第一个大于它的数的前面,第二个循环类似。设 (x) 表示一个中心点,要求两个循环的若干个数中分别至少有一个数在移动的时候经过 (x)。我们不妨把每次 moo 都是第一个循环的那个数和第二个循环的那个数互相搭配。

    如果要让 moo 的次数多,那么就意味着让 (x) 前后更多数相搭配。归纳一下,我们给 (a) 数组离散化得到排名数组 (r),那么相搭配必定是 (x) 前的数的排名要大于 (x)(x) 后的数相反。答案即:

    [max_{x=1}^{n}{(sum_{ileq x,r_i>x}1)} ]

    然后就可以树状数组维护了。

    代码:

    const int N = 1e5 + 10;
    
    int n;
    struct node
    {
    	int id, val;
    }a[N];
    int t[N], ans = 1;
    
    void modify(int x){for (; x <= n; x += x & -x) t[x]++;}
    int query(int x){int ans = 0;for (; x; x -= x & -x) ans += t[x]; return ans;}
    
    bool cmp(node a, node b){return a.val < b.val;} 
    bool cmp2(node a, node b){return a.id < b.id;} 
    
    int main()
    {
    //	freopen(".in", "r", stdin);
    //	freopen(".out", "w", stdout);
    	scanf ("%d", &n);
    	for (int i = 1; i <= n; i++)
    		scanf ("%d", &a[i].val), a[i].id = i;
    	sort (a + 1, a + 1 + n, cmp);
    	for (int i = 1; i <= n; i++) a[i].val = i;
    	sort (a + 1, a + 1 + n, cmp2);
    	for (int i = 1; i <= n; i++)
    	{
    		modify(a[i].val);
    		ans = max(ans, i - query(i));
    	}
    	printf ("%d
    ", ans);
        return 0;
    
  • 相关阅读:
    mysql主从复制
    gitlab安装
    nginx新加模块编译
    flask编写prometheus采集指标脚本
    powerdns的安装
    grafana中prometheus的查询语句
    python编写prometheus的监控指标
    maven常用命令参数
    flask架构中的方法学习
    Java命名规范
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/14419835.html
Copyright © 2011-2022 走看看