【金凌模拟试题】:数列
Time Limit:10000MS Memory Limit:65536K
Total Submit:36 Accepted:5
Description
- 问题描述
一个简单的数列问题:给定一个长度为n的数列,求这样的三个元素ai, aj, ak的个数,满足ai < aj > ak,且i < j < k。
Input
第一行是一个整数n(n <= 50000)。
第二行n个整数ai(0 <= ai <= 50000)。
Output
一个数,满足ai < aj > ak (i < j < k)的个数。
Sample Input
5
1 2 3 4 1
Sample Output
6
线段树。。
用l[i] 和r[i]分别存放a[i]两边比a[i]小的个数。注意ans要用__int64的
下面是AC代码:
#include<iostream> using namespace std; #define N 50002 struct node { int l,m,r; int num; }trie[N*3]; int l[N],r[N],a[N]; void creat(int id,int beg,int end) { trie[id].l=beg; trie[id].r=end; trie[id].num=0; trie[id].m=(beg+end)>>1; if(beg<end) { creat(id*2,trie[id].l,trie[id].m); creat(id*2+1,trie[id].m+1,trie[id].r); } } void update(int id,int goal,int val) { if(trie[id].l==goal&&trie[id].r==goal) { trie[id].num+=val; return ; } else { if(trie[id].m>=goal) { trie[id].num+=val; update(id*2,goal,val); //在左子树 } else { trie[id].num+=val; update(id*2+1,goal,val); //在右子树 } } } void find(int id,int beg,int end,int &max) { if(trie[id].l==beg&&trie[id].r==end) { max+=trie[id].num; } else { if(trie[id].m>=end) { find(id*2,beg,end,max); } else if(trie[id].m<beg) { find(id*2+1,beg,end,max); } else { find(id*2,beg,trie[id].m,max); find(id*2+1,trie[id].m+1,end,max); } } } int main() { int n,i,max; __int64 ans=0; cin>>n; creat(1,0,50000); for(i=1;i<=n;i++) { scanf("%d",&a[i]); update(1,a[i],1); max=0; if(a[i]==0) l[i]=0; else { find(1,0,a[i]-1,max); // printf("%d\n",a[i]); l[i]=max; } } creat(1,0,50000); for(i=n;i>=1;i--) { update(1,a[i],1); max=0; if(a[i]==0) r[i]=0; else { find(1,0,a[i]-1,max); r[i]=max; } } for(i=1;i<=n;i++) ans+=l[i]*r[i]; printf("%I64d\n",ans); return 0; }