Title Link: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=13895
Test instructions: There are N table tennis players in a street, everyone has a skill value, now each game requires 3 people, two players, a referee, the referee must live between them, and his skill value must be between two players, how many kinds of games can be organized.
Notice the range of the skill values (1≤ai≤100000), so we can handle the tree array (O (NLOGN)) to get a ll array, Ll[x] represents the number of people who live on the left side of X and whose skill value is less than X. Similar to the inverse process, get an array of RRS, Rr[x] represents the number of people who live on the right of X and whose skill value is less than X.
The final answer is:
< Span class= "Sh-symbol" > ans += ll[i] Span class= "Sh-symbol" >* (n -i -Rr[i]) + (i -1 -ll[i * rr[i (1< = x <= N)
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#defineMAXN 100010#defineMAXM 20010using namespaceStd;typedefLong LongLL;intPLAYER[MAXM], C[MAXN], LL[MAXN], RR[MAXN], N;intLowbit (intx);voidAddintXintu);intSumintx);intMainvoid){ intncase; scanf ("%d", &ncase); while(ncase--) {scanf ("%d", &N); for(inti =1; I <= N; ++i) {scanf ("%d", Player +i); } memset (c,0,sizeof(c)); for(inti =1; I <= N; ++i) {Ll[i]= SUM (Player[i]-1); Add (Player[i],1); } memset (c,0,sizeof(c)); for(inti = n; I >=1; --i) {Rr[i]= SUM (Player[i]-1); Add (Player[i],1); } LL ans=0; for(inti =1; I <= N; ++i) {ans+ = ll[i] * (N-i-rr[i]) + (I-1-Ll[i]) *Rr[i]; } printf ("%lld\n", ans); } return 0;}intLowbit (intx) { returnx& (-x);}voidAddintXintu) { while(x <=MAXN) {C[x]+=u; X+=lowbit (x); }}intSumintx) { intresult =0; while(X >0) {result+=C[x]; X-=lowbit (x); } returnresult;}
< Span class= "Sh-symbol" > < Span class= "Sh-symbol" > < Span class= "Sh-symbol" >
/span>
Uvalive 4329 Ping pong (tree-like array)