在完成了分配任務之后,西部314來到了樓蘭古城的西部。
相傳很久以前這片土地上(比樓蘭古城還早)生活著兩個部落,一個部落崇拜尖刀(‘V’),一個部落崇拜鐵鍬(‘∧’),他們分別用V和∧的形狀來代表各自部落的圖騰。
西部314在樓蘭古城的下面發現了一幅巨大的壁畫,壁畫上被標記出了N個點,經測量發現這N個點的水平位置和豎直位置是兩兩不同的。
西部314認為這幅壁畫所包含的信息與這N個點的相對位置有關,因此不妨設坐標分別為(1,y1),(2,y2),…,(n,yn)(1,y1),(2,y2),…,(n,yn),其中y1y1~ynyn是1到n的一個排列。
西部314打算研究這幅壁畫中包含著多少個圖騰。
如果三個點(i,yi),(j,yj),(k,yk)(i,yi),(j,yj),(k,yk)滿足1≤i<j<k≤n且yi>yj,yj<yk1≤i<j<k≤n且yi>yj,yj<yk,則稱這三個點構成V圖騰;
如果三個點(i,yi),(j,yj),(k,yk)(i,yi),(j,yj),(k,yk)滿足1≤i<j<k≤n且yi<yj,yj>yk1≤i<j<k≤n且yi<yj,yj>yk,則稱這三個點構成∧圖騰;
西部314想知道,這n個點中兩個部落圖騰的數目。
因此,你需要編寫一個程序來求出V的個數和∧的個數。
輸入格式
第一行一個數n。
第二行是n個數,分別代表y1,y2,…,yny1,y2,…,yn。
輸出格式
兩個數,中間用空格隔開,依次為V的個數和∧的個數。
數據范圍
對于所有數據,n≤200000n≤200000,且輸出答案不會超過int64。
輸入樣例:
5
1 5 3 2 4
輸出樣例:
3 4
不明白為什么不需要離散化
代碼:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<cmath>
const int maxn=2e5+5;
typedef long long ll;
using namespace std;
struct node
{
int l,r;
int num;
}tree[maxn<<2];
vector<int>v;
int a[maxn];
void pushup(int m)
{
tree[m].num=(tree[m<<1].num+tree[m<<1|1].num);
}
void build(int m,int l,int r)
{
tree[m].l=l;
tree[m].r=r;
tree[m].num=0;
if(l==r)
{
return ;
}
int mid=(tree[m].l+tree[m].r)>>1;
build(m<<1,l,mid);
build(m<<1|1,mid+1,r);
}
void update(int m,int pos,int val)
{
if(tree[m].l==tree[m].r)
{
tree[m].num+=val;
return;
}
int mid=(tree[m].l+tree[m].r)>>1;
if(pos<=mid)
{
update(m<<1,pos,val);
}
else
{
update(m<<1|1,pos,val);
}
pushup(m);
}
int query(int m,int l,int r)
{
if(tree[m].l==l&&tree[m].r==r)
{
return tree[m].num;
}
int mid=(tree[m].l+tree[m].r)>>1;
if(r<=mid)
{
return query(m<<1,l,r);
}
else if(l>mid)
{
return query(m<<1|1,l,r);
}
else
{
return query(m<<1,l,mid)+query(m<<1|1,mid+1,r);
}
}
ll minl[maxn],minr[maxn],maxl[maxn],maxr[maxn];
int main()
{
int n;
cin>>n;
for(int t=1;t<=n;t++)
{
scanf("%d",&a[t]);
}
build(1,0,n+1);
for(int t=1;t<=n;t++)
{
minl[t]=query(1,0,a[t]-1);
maxl[t]=query(1,a[t]+1,n+1);
update(1,a[t],1);
}
build(1,0,n+1);
for(int t=n;t>=1;t--)
{
minr[t]=query(1,0,a[t]-1);
maxr[t]=query(1,a[t]+1,n+1);
update(1,a[t],1);
}
ll ans1=0,ans2=0;
for(int t=1;t<=n;t++)
{
ans1+=maxl[t]*maxr[t];
ans2+=minl[t]*minr[t];
}
printf("%lld %lld\n",ans1,ans2);
system("pause");
return 0;
}