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++

  • 相关阅读:
    [Leetcode]设计链表
    [Leetcode]最小栈
    复杂JSON反序列化为类对象
    Big Data Solution in Azure: Azure Data Lake
    EF vs ADO.NET
    EF5.0默认不支持DB First了?
    WebService/WCF/WebAPI区别
    AugularJS1.X不升级到2.X
    数据库中锁的问题
    MVC中路由匹配的规则
  • 原文地址:https://www.cnblogs.com/wzc521/p/11813489.html
Copyright © 2011-2022 走看看