题目大意:
我们有一个数列,数列中有n个数,对于一个数ai,在它左边的比他大的数的个数为li,右边比他大的数的个数为ri,若li,ri中的较大者比较小者的两倍还大,那么他就是一个不平衡数,求不平衡数的数量。
好吧,典型逆序对。
因为我们要求左边比他大的数的个数,所以我们倒着排序,然后再离散。
然后树状数组解决问题。
那么右边怎么办?
很显然我们得到的离散数组的值就是比他大的数的个数+1(它本身),所以右边的答案为:离散数组值-左边比他大的数的个数-1;
然后轻松统计答案
下面贴代码
#include<cstdio> #include<algorithm> #define MN 100005 using namespace std; int n,tot; int b[MN],t[MN]; struct qaq{ int num,opt; }a[MN]; int lowbit(int x){return (x&-x);} int query(int x) { int ans=0; while(x) { ans+=t[x]; x-=lowbit(x); } return ans; } void update(int x){ while(x<=n) { t[x]++; x+=lowbit(x); } } bool cmp(qaq a,qaq b){return a.num>b.num;} int main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i].num),a[i].opt=i; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++)b[a[i].opt]=i; for(int i=1;i<=n;i++) { int l=query(b[i]),r=b[i]-l-1; if ((l*2<r)||(r*2<l))tot++; update(b[i]); } printf("%d\n",tot); // fclose(stdin); // fclose(stdout); }
时间: 2024-10-25 13:27:35