zoukankan      html  css  js  c++  java
  • [JZO6401]:Time(贪心+树状数组)

    题目描述

      小$A$现在有一个长度为$n$的序列${x_i}$,但是小$A$认为这个序列不够优美。
      小$A$认为一个序列是优美的,当且仅当存在$kin [1,n]$,满足:
    $$x_1leqslant x_2leqslant...leqslant x_kgeqslant x_{k+1}geqslant...geqslant x_n$$
      现在小$A$可以进行若干次操作,每次可以交换序列中相邻的两个项,现在他想知道最少操作多少次之后能够使序列变为优美的。


    输入格式

      第一行一个正整数$n$,表示序列的长度。
      接下来一行$n$个整数,表示初始的序列。


    输出格式

      输出一行一个整数,表示最少需要的操作次数。


    样例

    样例输入:

    5
    3 4 5 1 2

    样例输出:

    1


    数据范围与提示

      对于$30\%$的数据,$nleqslant 12$
      对于$60\%$的数据,$nleqslant 100,000$,$a_i$互不相同
      对于$100\%$的数据,$n,a_ileqslant 100,000$


    题解

    考虑贪心,一定是挨个将最小的数移到两端不劣。

    至于过程直接用树状数组维护就好了,交换次数就是一侧比它大的数的个数。

    时间复杂度:$Theta(nlog n)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    int a[100001],cnt;
    int tr[100001];
    long long ans;
    vector<int> vec[100001];
    int lowbit(int x){return x&-x;}
    void add(int x){for(int i=x;i<=n;i+=lowbit(i))tr[i]++;}
    void del(int x){for(int i=x;i<=n;i+=lowbit(i))tr[i]--;}
    int ask(int x){int res=0;for(int i=x;i;i-=lowbit(i))res+=tr[i];return res;}
    int main()
    {
    	scanf("%d",&n);cnt=n;
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    	for(int i=1;i<=n;i++){add(i);vec[a[i]].push_back(i);}
    	for(int i=1;i<=n;i++)
    		for(int j=0;j<vec[i].size();j++)
    		{
    			int x=ask(vec[i][j]-1),y=cnt-x-1;
    			ans+=min(x,(int)(y-vec[i].size()+j+1));
    			del(vec[i][j]);cnt--;
    		}
    	printf("%lld",ans);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    Android OpenGL ES 2.0 (四) 灯光perfragment lighting
    Android OpenGL ES 2.0 (五) 添加材质
    冒泡排序函数
    javascript object 转换为 json格式 toJSONString
    Liunx CentOS 下载地址
    jquery 图片切换特效 鼠标点击左右按钮焦点图切换滚动
    javascript 解析csv 的function
    mysql Innodb Shutdown completed; log sequence number解决办法
    Centos 添加 yum
    javascript 键值转换
  • 原文地址:https://www.cnblogs.com/wzc521/p/11813489.html
Copyright © 2011-2022 走看看