P1637 三元上升子序列

题面

https://www.luogu.org/problem/P1637

题解

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node{
  int x,val;
  bool operator < (const node rhs) const {
    return val<rhs.val;
  }
} a[30500];
int tree[30500],f[30500],n;

long long cha(int x){
  int i;
  long long sum=0;
  for (i=x;i>=1;i-=i&(-i)) sum+=tree[i];
  return sum;
}

void add(int x,int s){
  for (int i=x;i<=n;i+=i&(-i)) tree[i]+=s;
}

int main(){
  int x,i,j;
  scanf("%d",&n);
  for (i=1;i<=n;i++) {
    scanf("%d",&x);
    a[i]=(node){i,x};
  }
  sort(a+1,a+n+1);
  long long ans=0,xx;
  for (i=1;i<=n;i++) {
    for (j=i;a[j].val==a[i].val;j++) {
      xx=cha(a[j].x);
      f[j]=xx;
    }
    for (j=i;a[j].val==a[i].val;j++) add(a[j].x,1);
    i=j-1;
  }
  memset(tree,0,sizeof(tree));

  for (i=1;i<=n;i++) {
    for (j=i;a[j].val==a[i].val;j++) {
      xx=cha(a[j].x);
      ans+=xx;
    }
    for (j=i;a[j].val==a[i].val;j++) add(a[j].x,f[j]);
    i=j-1;
  }
  cout<<ans<<endl;
  return 0;
}

 

posted @ 2019-08-29 00:16  HellPix  阅读(194)  评论(0编辑  收藏  举报