本题的题意分析与代码梳理
/*
已知了treap是 二叉搜索树和 堆的结合,
那去掉了 堆就是二叉搜索树了
去掉堆,意味着去掉 zag,zig,和val
下面是 treap这个结合体的代码
*/
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
const int mode=1e9+7,INF=1e8;
typedef long long LL;
int n;
int C[N][N];
int a[N];
struct Node
{
int l,r;
int key,val;
int siz;
}tr[N];
int root,idx;
void pushup(int p)
{
tr[p].siz=tr[tr[p].l].siz+tr[tr[p].r].siz+1;
}
void zig(int &p)
{
int q=tr[p].l;
tr[p].l=tr[q].r;
tr[q].r=p;
p=q;
pushup(p),pushup(tr[p].r);
}
void zag(int &p)
{
int q=tr[p].r;
tr[p].r=tr[q].l;
tr[q].l=p;
p=q;
pushup(p),pushup(tr[p].l);
}
void init()
{
for(int a=0;a<N;a++)
for(int b=0;b<=a;b++)
{
if(b==0) C[a][b]=1;
else C[a][b]=(C[a-1][b-1]+C[a-1][b])%mode;
}
}
int get_node(int key)
{
tr[++idx].key=key;
tr[idx].siz=1;
//tr[idx].val=rand();
return idx;
}
void build()
{
get_node(-INF),get_node(INF);
root=1,tr[1].r=2;
pushup(root);
// if(tr[1].val<tr[2].val)
// {
zag(root);
//}
}
void insert(int &p,int key)
{
if(!p)
{
p=get_node(key);
}
else if(key<tr[p].key)
{
insert(tr[p].l,key);
//if (tr[tr[p].l].val > tr[p].val)
//zig(p);
}
else if(key>tr[p].key)
{
insert(tr[p].r,key);
//if (tr[tr[p].r].val > tr[p].val)
//zag(p);
}
else if(key==tr[p].key)
{
return;
}
pushup(p);
}
int dfs(int p)
{
if(!p) return 1;
LL l=dfs(tr[p].l);
LL r=dfs(tr[p].r);
int lson=tr[p].l,rson=tr[p].r;
int lnum=tr[lson].siz,rnum=tr[rson].siz;
return l*r%mode*C[lnum+rnum][lnum]%mode;
}
int main()
{
init();
while(cin>>n)
{
idx=0;
for(int i=1;i<N;i++) //一开始没有正确结果就在于这里,没有设置为0
{
tr[i].l=tr[i].r=tr[i].key=tr[i].val=tr[i].siz=0;
}
build();
for(int i=1;i<=n;i++ ) cin>>a[i];
for(int i=1;i<=n;i++)
{
insert(root,a[i]);
}
cout<<dfs(root)<<endl;
}
}