P1637 三元上升子序列
题目描述
Erwin最近对一种叫"thair"的东西巨感兴趣。。。
在含有n个整数的序列a1,a2......an中,
三个数被称作"thair"当且仅当i<j<k且ai<aj<ak
求一个序列中"thair"的个数。
输入输出格式
输入格式:开始一个正整数n,
以后n个数a1~an。
输出格式:"thair"的个数
输入输出样例
输入样例#1:
4
2 1 3 4
输出样例#1:
2
输入样例#2:
5
1 2 2 3 4
输出样例#2:
7
说明
对样例2的说明:
7个"thair"分别是
1 2 3 1 2 4 1 2 3 1 2 4 1 3 4 2 3 4 2 3 4 约定 30%的数据n<=100
60%的数据n<=2000
100%的数据n<=30000
大数据随机生成
0<=a[i]<=maxlongint
Solution:
本题实际很水的。。。
先离散化,用树状数组求出每个数前面比它小的数的个数$a_i$,再求出每个数后面比它大的个数$b_i$,则$ans=\sum{a_i*b_i},i\in[1,n]$。
输出$ans$就$ok$了(注意答案可能爆$long\;long$)。
代码:
#include<bits/stdc++.h> #define ll long long #define il inline #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int N=100005; ll n,m,a[N],tr[N],tot[N]; ll ans; struct node{ int v,id; bool operator < (const node a)const{return v<a.v;} }q[N]; il int gi() { int a=0;char x=getchar();bool f=0; while((x<'0'||x>'9')&&x!='-')x=getchar(); if(x=='-')x=getchar(),f=1; while(x>='0'&&x<='9')a=a*10+x-48,x=getchar(); return f?-a:a; } il void update(int k){while(k<=n){tr[k]++;k+=k&-k;}} il ll query(int k){ll sum=0;while(k){sum+=tr[k];k-=k&-k;}return sum;} int main(){ n=gi(); for(int i=1;i<=n;i++)q[i].v=gi(),q[i].id=i; sort(q+1,q+n+1);q[0].v=-10000000; for(int i=1;i<=n;i++)if(q[i].v!=q[i-1].v)a[q[i].id]=++m;else a[q[i].id]=m; for(int i=1;i<=n;i++)update(a[i]),tot[i]=query(a[i]-1); memset(tr,0,sizeof(tr)); for(int i=n;i>=1;i--){update(a[i]);if(tot[i])ans+=tot[i]*(query(n)-query(a[i]));} cout<<ans; return 0; }
PS:~蒟蒻写博客不易,转载请注明出处,万分感谢!~