rt.好像没必要动态开点 但是来练练手
样例会卡死
#include <iostream>
using namespace std;
typedef long long ll;
const int Maxn=3e4+5,Maxa=1e5+5;
int n,a[Maxn],num=1;
struct Segt
{
int l,r,dat;
}t[Maxn<<6];
void build()
{
t[1].l=0;
t[1].r=Maxa;
}
void clear()
{
for(int i=1;i<=(Maxn<<6);i++) t[i].dat=t[i].l=t[i].r=0;
}
void pushup(int p)
{
t[p].dat=t[t[p].l].dat+t[t[p].r].dat;
}
void modify(int p,int l,int r,int x)
{
if(l==r) t[p].dat++;
int mid=(l+r)>>1;
if(!t[p].l) t[p].l=++num;
if(!t[p].r) t[p].r=++num;
if(x<=mid) modify(t[p].l,l,mid,x);
else modify(t[p].r,mid+1,r,x);
pushup(p);
}
int query(int p,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return t[p].dat;
int mid=(l+r)>>1,ret=0;
if(ql<=mid&&t[p].l) ret+=query(t[p].l,l,mid,ql,qr);
if(mid<qr&&t[p].r) ret+=query(t[p].r,mid+1,r,ql,qr);
return ret;
}
int bigger[Maxn],smaller[Maxn];
int main()
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build();
for(int i=1;i<=n;i++)
{
modify(1,0,Maxa,a[i]);
if(a[i]) smaller[i]=query(1,0,Maxa,0,a[i]-1);
}
clear();
build();
for(int i=n;i>=1;i--)
{
modify(1,0,Maxa,a[i]);
bigger[i]=query(1,0,Maxa,a[i]+1,Maxa);
}
ll ans=0;
for(int i=2;i<n;i++) ans+=bigger[i]+smaller[i];
}