题意:
一串数字 问 有几种这样的组合(x,y,z)使得x>y>z或x<y<z y在x数字后面z在y后面 题目中每种数字是唯一的
思路:
对于一个数字 比如 f 它计算出的ans值为
( beforef.lessthanf * afterf.biggerthanf )+( beforef.biggerthanf * afterf.lessthanf )
易知 beforef.biggerthanf = locationf - 1 - beforef.lessthanf 同理after
则式子可化简为
( beforef.lessthanf * ( n - locationf - afterf.lessthanf ) )+( (
locationf - 1 - beforef.lessthanf ) * afterf.lessthanf )
如果我们从小到大的处理每个数字 那么可知当前处理的数字是当前序列中最大的
则 afterf.lessthanf = nowallnumber - beforef.lessthanf
那么式子中将只出现一个未知数 也就是说我们只需要知道当前位置前有几个小于自己即可
因此用树状数组维护
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 20010 #define lowbit(x) (x&(-x)) int t,n; int a[N]; __int64 ans; struct person { int id,val; bool operator<(const person fa) const { return val<fa.val; } }f[N]; void add(int x) { while(x<=n) { a[x]+=1; x+=lowbit(x); } } int sum(int x) { int res=0; while(x) { res+=a[x]; x-=lowbit(x); } return res; } int main() { int i,ls,lb,rs,rb,id; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) { f[i].id=i; scanf("%d",&f[i].val); } sort(f+1,f+1+n); memset(a,0,sizeof(a)); ans=0; for(i=1;i<=n;i++) { id=f[i].id; ls=sum(id); lb=id-ls-1; rs=sum(n)-ls; rb=n-id-rs; ans+=ls*rb; ans+=lb*rs; add(id); } printf("%I64d\n",ans); } return 0; }
HDU 2492 Ping pong
时间: 2024-10-09 06:50:51