此时答案
a
n
s
=
∑
i
=
1
n
l
[
i
]
∗
r
[
i
]
ans = \sum_{i=1}^{n}l[i]*r[i]
ans=∑i=1nl[i]∗r[i]
对于^图腾的求法
逆序扫描每个点右边比他纵坐标小的记为
r
[
i
]
r[i]
r[i]
正序扫描每个点左边纵坐标比他小的记为
l
[
i
]
l[i]
l[i]
此时答案
s
u
m
=
∑
i
=
1
n
l
[
i
]
∗
r
[
i
]
sum = \sum_{i=1}^{n}l[i]*r[i]
sum=∑i=1nl[i]∗r[i]
最后分别输出答案即可
扫描的过程可以用树状数组来进行
code
#include<bits/stdc++.h>usingnamespace std;typedeflonglong LL;constint maxn =2e5+100;template<typename T>inlinevoidread(T &s){
s =0;
T w =1, ch =getchar();while(!isdigit(ch)){if(ch =='-') w =-1; ch =getchar();}while(isdigit(ch)){ s =(s <<1)+(s <<3)+(ch ^48); ch =getchar();}
s *= w;}int n, sum;
LL a[maxn], r[maxn], l[maxn], c[maxn];inline LL max(LL aa, LL bb){return aa > bb ? aa : bb;}inline LL min(LL aa, LL bb){return aa < bb ? aa : bb;}inlineintlowbit(int x){return x &(-x);}inlinevoidadd(int x, LL val){for(; x <= n; x +=lowbit(x))
c[x]+= val;}inlineintquery(int x){int ans =0;for(; x; x -=lowbit(x))
ans += c[x];return ans;}intmain(){read(n);for(int i =1; i <= n;++i){read(a[i]);
sum =max(sum, a[i]);}
LL ans =0;for(int i = n; i >=1;--i){
r[i]+=query(sum)-query(a[i]);add(a[i],1);}memset(c,0,sizeof(c));for(int i =1; i <= n;++i){
l[i]+=query(sum)-query(a[i]);add(a[i],1);}for(int i =1; i <= n;++i)
ans += l[i]* r[i];printf("%lld ", ans);
ans =0;memset(r,0,sizeof(r));memset(l,0,sizeof(l));memset(c,0,sizeof(c));for(int i = n; i >=1;--i){
r[i]+=query(a[i]-1);add(a[i],1);}memset(c,0,sizeof(c));for(int i =1; i <= n;++i){
l[i]+=query(a[i]-1);add(a[i],1);}for(int i =1; i <= n;++i)
ans += l[i]* r[i];printf("%lld", ans);return0;}