版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhanghaoxian1/article/details/81909798
[Tyvj Jan]楼兰图腾
题目描述
在完成了分配任务之后,西部314来到了楼兰古城的西部。相传很久以前这片土地上(比楼兰古城还早)生活着两个部落,一个部落崇拜尖刀(‘V’),一个部落崇拜铁锹(‘∧’),他们分别用V和∧的形状来代表各自部落的图腾。
西部314在楼兰古城的下面发现了一幅巨大的壁画,壁画上被标记出了N个点,经测量发现这N个点的水平位置和竖直位置是两两不同的。西部314认为这幅壁画所包含的信息与这N个点的相对位置有关,因此不妨设坐标分别为(1,y1),(2,y2),…,(n,yn),其中y1~yn是1到n的一个排列。
西部314打算研究这幅壁画中包含着多少个图腾,其中V图腾的定义如下(注意:图腾的形式只和这三个纵坐标的相对大小排列顺序有关)1<=i
#include <cstdio>
#include <string>
#include <cstring>
#define N 200005
#define ll long long
using namespace std;
ll a[N],c[N],n;
struct arr
{
ll l,r;
}a1[N],a2[N];
void add(ll x, ll y)
{
while (x <= n)
{
c[x]+=y;
x+=x&(-x);
}
}
ll count(ll x)
{
ll sum = 0;
while (x > 0)
{
sum+=c[x];
x-=x&(-x);
}
return sum;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
for (int i = 1; i <= n; i++)
{
ll s = count(a[i]);
a1[i].l = s;
a2[i].l = i - 1 - s;
add(a[i], 1);
}
memset(c, 0, sizeof(c));
for (int i = n; i >= 1; i--)
{
ll s = count(a[i]);
a1[i].r = s;
a2[i].r = n - i - s;
add(a[i], 1);
}
ll ans = 0;
for (int i = 1; i <= n; i++)
ans+=a2[i].l * a2[i].r;
printf("%lld ", ans);
ans = 0;
for (int i = 1; i <= n; i++)
ans+=a1[i].l * a1[i].r;
printf("%lld\n", ans);
}