Main topic
Give a string of numbers, which is a permutation of 1 to N, to find out the number of three digits of the x<z<y (x, y, z in sequence)
Analysis
Just get the topic, there is a tree-like array processing than the current number of large or small feeling, at first I locked the Y, on the right and left of Y to find a smaller than the number of Y, but this can only guarantee z<y,x<y, can not guarantee x<z. So the final three numbers will be x<z<y, with z<x<y two possible. Sifting to Z<x<y is not a good deal.
So:
If you lock x to look for numbers larger than X on the right, you can get x<y<z, as well as x<z<y two possibilities. The x<y<z can be filtered by fixing Y to find the left side smaller than it, and the right is larger than it to count the method directly.
Note the data range when multiplying.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespacestd;#defineMax_num 100005#defineModd 100000007#defineLowbit (q) (q) & (-(q))typedefLong Long intLL;intC[max_num];voidUpdateinti) { for(intj = i; J <=1e5;) {C[j]++ ; J+=Lowbit (j); }}intQueryinti) { intsum =0; while(i) {sum+=C[i]; I-=lowbit (i); } returnsum;} LL Num[max_num]; LL Pre[max_num]; LL Las[max_num];intMainintargcChar Const*argv[]) { intT; scanf ("%d",&t); intvs =0; while(t--){ intN; scanf ("%d",&N); LL ans=0; Memset (c,0,sizeof(c)); for(inti =1; I <= N; i++) {scanf ("%lld",&Num[i]); Pre[i]= Query (num[i]-1); Update (num[i]); } memset (c,0,sizeof(c)); for(inti = n; i >0; i--) {Las[i]= (n-i)-query (Num[i]); Ans= (ans + (las[i]* (las[i]-1))/2-(pre[i]*las[i]))%modd; Update (num[i]); } printf ("Case #%d:%lld\n",++Vs,ans); } return 0;}
HDU-4000 Fruit Ninja (tree-like array)