正题
题目大意
给若干个点,求可以得到/\和V的形状各多少个。
解题思路
我们可以用树状数组求逆序对的方法求出一个点左边 小于/大于 和右边 小于/大于 的数量各多少个,然后乘一下就好了。
code
#include<cstdio>
#include<algorithm>
#include<cstring>
#define lobit(x) x&-x
using namespace std;
int t[200011],n,x;
long long ans1,ans2;
void add(int x,int num)
{
while(x<=n)
{
t[x]+=num;
x+=lobit(x);
}
}
int ask(int x)
{
int sum=0;
while(x>0)
{
sum+=t[x];
x-=lobit(x);
}
return sum;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
int k=ask(x-1);
ans1+=(long long)(i-k-1)*(n-i-x+k+1);//求以i为中心的/\
ans2+=(long long)k*(x-1-k);//求以i为中心的V
add(x,1);
}
printf("%lld %lld",ans1,ans2);
}