Luogu P1637 삼항 오름차순 하위 시퀀스

Luogu P1637 삼항 오름차순 하위 시퀀스

주제 링크

제목 설명

Erwin은 최근 thair라는 것에 매우 관심을 갖게되었습니다. . .

nn 포함n 개의 정수 시퀀스a 1, a 2,…, a_1, a_2, \ ldots, a_n(1),,,Ni <j <k i <j <k 인 경우에만 세 개의 숫자를 thair라고합니다.나는<제이<kai <aj <ak a_i <a_j <a_k나는<J<케이

시퀀스에서 thair의 수를 찾으십시오.

입력 형식

양의 정수 nn 으로 줄 시작n ,

다음 줄 nnn个整수a 1, a 2, ..., an a_1, a_2, \ ldots, a_n(1),,,N

출력 형식

한 줄의 정수는 thair의 수를 나타냅니다.

견본

# 1 입력

4
2 1 3 4

출력 # 1

2

입력 # 2

5
1 2 2 3 4

출력 # 2

7

일반적인 가중 선분 트리는 먼저 데이터를 이산화 한 다음 각 숫자에 대해 a [i] a [i]a [ i ] 선분 트리에서 이보다 작게 찾기l [i] l [i]l [ i ] 일본r [i] r [i]r [ i ]는 괜찮습니다. 마지막으로l [i] ∗ r [i] l [i] * r [i]l [ i ]r [ i ] 가 답이고 AC 코드는 다음과 같습니다.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e4+5;
typedef long long ll;
int n,m,k;
ll a[N],l[N],r[N],tree[N<<2];
vector<ll>v;
int getpos(ll x){
    
    
    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}

void pushup(int i)
{
    
    
    tree[i]=tree[i<<1]+tree[i<<1|1];
}

void build(int i,int l,int r)
{
    
    
    if(l==r)
    {
    
    
        tree[i]=0;
        return ;
    }
    int mid=l+r>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    pushup(i);
}

void update(int i,int l,int r,int x,int k)
{
    
    
    if(l==r)
    {
    
    
        tree[i]+=k;
        return ;
    }
    int mid=l+r>>1;
    if(x<=mid) update(i<<1,l,mid,x,k);
    else update(i<<1|1,mid+1,r,x,k);
    pushup(i);
}

ll query(int i,int l,int r,int m,int n)
{
    
    
    if(m<=l&&r<=n) return tree[i];
    int mid=l+r>>1;
    ll ans=0;
    if(m<=mid) ans+=query(i<<1,l,mid,m,n);
    if(n>mid) ans+=query(i<<1|1,mid+1,r,m,n);
    return ans;
}

int main(){
    
    
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
    
    
        scanf("%d",&a[i]);
        v.push_back(a[i]);
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    n=v.size();
    for(int i=1;i<=m;i++){
    
    
        int pos=getpos(a[i]);
        if(pos!=1) l[i]=query(1,1,n,1,pos-1);
        update(1,1,n,getpos(a[i]),1);
    }
    memset(tree,0,sizeof((tree)));
    for(int i=m;i>=1;i--){
    
    
        int pos=getpos(a[i]);
        if(pos!=n) r[i]=query(1,1,n,getpos(a[i])+1,n);
        update(1,1,n,getpos(a[i]),1);
    }
    ll ans=0;
    for(int i=1;i<=m;i++) ans+=l[i]*r[i];
    printf("%lld",ans);
    return 0;
}

추천

출처blog.csdn.net/qq_43765333/article/details/108626814