hoj2275: Number sequence
hoj2275: http://acm.hit.edu.cn/hoj/problem/view?id=2275
题意:给一个数列,问有多少组满足:三个数Ai < Aj > Ak 且 i < j < k.
解法:树状数组:用数组left存储所有比左边的数小的数的个数,则结果为left值*(所有比右边的数小的数的个数)
code:
#include<iostream> #include<cstdlib> #include<cstdio> int num[50010],c[50010],left[50010]; long long s; int lowbit(int x) { return x&(-x); } int sum(int x) { int ss=0; //ss为所有比x小的数的个数,因为顺序枚举(边输入边枚举),所以只表示所有比x小且在x左边的数的个数 while(x>0) { ss+=c[x]; x-=lowbit(x); } return ss; } void modify(int x) //讲x插入 { while(x<50010) { c[x]++; //c[x]为x的个数 x+=lowbit(x); } } int main() { int n; while(scanf("%d",&n)!=EOF) { memset(c,0,sizeof(c)); //初始化为0 for(int i=1;i<=n;i++) { scanf("%d",&num[i]); left[i]=sum(num[i]-1); //注意要减一,因为是小于,不包含与本身相等的数 modify(num[i]); } memset(c,0,sizeof(c)); //注意要重新初始化为0 s=0; for(int i=n;i>=1;i--) { s=s+sum(num[i]-1)*left[i]; //即s=s+right[i]*left[i] modify(num[i]); } printf("%lld\n",s); } } /*input: 5 1 2 3 4 1 output: 6*/