[JZOJ] 3462. 【NOIP2013模拟联考5】休息(rest)

https://jzoj.net/senior/#main/show/3462

分成最少段就是分成极大段下降子串,这一步暴力完成,然后剩下的就是一个冒泡排序,统计逆序对即可。

复杂度O(nlogn)

#include<iostream>
#include<cstdio>

using namespace std;

inline int rd(){
    int ret=0,f=1;char c;
    while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
    while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    return ret*f;
}

const int MAXN=100005;

int t[MAXN];
int n,val[MAXN],tot;
int sta[MAXN],top;
void update(int x,int w){
    for(int i=x;i<=n;i+=i&-i) t[i]+=w;
}
int query(int x){
    int ret=0;
    for(int i=x;i;i-=i&-i) ret+=t[i];
    return ret;
}

int main(){
    n=rd();
    int x;
    long long ans=0;
    for(int i=1;i<=n;i++){
        x=rd();
        if(x<sta[top]){sta[++top]=x;continue;}
        while(top) val[++tot]=sta[top--];
        sta[++top]=x;ans++;
    }
    while(top) val[++tot]=sta[top--];
    for(int i=n;i>=1;i--) ans+=query(val[i]-1),update(val[i],1);
    cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ghostcai/p/9427235.html