[CH4201] Loulan Totem

I use tree array to solve this problem After we read in the data, we analyze the problem and solve two problems: the number of '^' and the n...

I use tree array to solve this problem

After we read in the data, we analyze the problem and solve two problems: the number of '^' and the number of 'v'. Let's first consider^

Suppose we make the vertex whose i is ^, then the number of ^ whose i is the vertex is the product of the number of heights whose left side height is less than i and the number whose right side height is less than i. We just need to enumerate the positions of i and accumulate the answers.

How can we efficiently maintain the number of sides less than i height? We build a tree array (of course, the line tree can also) to store the number of times each height appears.

We are enumerating I in positive order. For each I, we look for the number of 0~a[i]-1 in the tree array, which is the number of heights on the left side of I that are less than I. after the search is completed, we put the height of a[i] in the tree array + 1, indicating that it has occurred once.

We can do another reverse enumeration to find out the number that the height on the right side of i is less than i. Then we can work out the number of ^

Similarly, we can also solve for the number of V.

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 const int N=200010; 8 int n,a[N],sum[N]; 9 ll ans,l[N],r[N]; 10 inline int read() { 11 int ret=0; 12 int op=1; 13 char c=getchar(); 14 while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();} 15 while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar(); 16 return ret*op; 17 } 18 inline int lowbit(int x) { 19 return -x&x; 20 } 21 inline int query(int x) { 22 int ret=0; 23 while(x) { 24 ret+=sum[x]; 25 x-=lowbit(x); 26 } 27 return ret; 28 } 29 inline void add(int x) { 30 while(x<=n) { 31 sum[x]++; 32 x+=lowbit(x); 33 } 34 } 35 int main() { 36 n=read(); 37 for(int i=1;i<=n;i++) a[i]=read(); 38 for(int i=1;i<=n;i++) { 39 l[i]=query(n)-query(a[i]); 40 add(a[i]); 41 } 42 memset(sum,0,sizeof(sum)); 43 for(int i=n;i>=1;i--) { 44 r[i]=query(n)-query(a[i]); 45 add(a[i]); 46 } 47 for(int i=1;i<=n;i++) 48 ans+=(long long)l[i]*r[i]; 49 printf("%lld ",ans); 50 ans=0; 51 memset(sum,0,sizeof(sum)); 52 memset(l,0,sizeof(l)); 53 memset(r,0,sizeof(r)); 54 for(int i=1;i<=n;i++) { 55 l[i]=query(a[i]-1); 56 add(a[i]); 57 } 58 memset(sum,0,sizeof(sum)); 59 for(int i=n;i>=1;i--) { 60 r[i]=query(a[i]-1); 61 add(a[i]); 62 } 63 for(int i=1;i<=n;i++) 64 ans+=(long long)l[i]*r[i]; 65 printf("%lld",ans); 66 return 0; 67 }
AC Code

5 November 2019, 16:06 | Views: 4014

Add new comment

For adding a comment, please log in
or create account

0 comments