# 震惊！Vector两行代码求逆序对，六行代码过普通平衡树

## Vector两行代码求逆序对

 1 #include<cstdio>
2 #include<algorithm>
3 #include<vector>
4 using namespace std;
5 int n,m,ans,a[100001];
6 vector<int>v;
7 int main()
8 {
9     scanf("%d",&n);
10     for(int i=1;i<=n;i++)    scanf("%d",&a[i]);
11     for(int i=1;i<=n;i++)
12     {
13         int now=upper_bound(v.begin(),v.end(),a[i])-v.begin();
14         ans=ans+i-now-1,v.insert(v.begin()+now,a[i]);
15     }
16     printf("%d",ans);
17     return 0;
18 }

update in 2017.12.16

#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN=1e6+10;
const int maxn=0x7fffff;
inline char nc()
{
static char buf[MAXN],*p1=buf,*p2=buf;
}
{
char c=nc();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
return x*f;
}
#define root tree[0].ch[1]
struct node
{
int v,fa,ch[2],rec,sum;
};
node tree[MAXN];
int pointnum,tot;
int iden(int x){return tree[tree[x].fa].ch[0]==x?0:1;}
inline void connect(int x,int fa,int how){tree[x].fa=fa;tree[fa].ch[how]=x;}
inline void update(int x){tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;}
inline void rotate(int x)
{
int y=tree[x].fa;
int R=tree[y].fa;
int Rson=iden(y);
int yson=iden(x);
int b=tree[x].ch[yson^1];
connect(b,y,yson);
connect(y,x,yson^1);
connect(x,R,Rson);
update(y);update(x);
}
void splay(int pos,int to)// 把编号为pos的节点旋转到编号为to的节点
{
to=tree[to].fa;
while(tree[pos].fa!=to)
{
if(tree[tree[pos].fa].fa==to)    rotate(pos);
else if(iden(tree[pos].fa)==iden(pos))    rotate(tree[pos].fa),rotate(pos);
else    rotate(pos),rotate(pos);
}
}
inline int newpoint(int v,int fa)//
{
tree[++tot].fa=fa;
tree[tot].v=v;
tree[tot].sum=tree[tot].rec=1;
}
inline void dele(int x)
{
tree[x].ch[0]=tree[x].ch[1]=0;
if(x==tot)  tot--;
}
int find(int v)
{
int now=root;
while(1)
{
if(tree[now].v==v)   {splay(now,root);return now;}
int nxt=v<tree[now].v?0:1;
if(!tree[now].ch[nxt])return 0;
now=tree[now].ch[nxt];
}
}
int build(int v)
{
pointnum++;
if(tot==0){root=1;newpoint(v,0);}
else
{
int now=root;
while(1)
{
tree[now].sum++;
if(tree[now].v==v){tree[now].rec++;return now;}//出现过
int nxt=v<tree[now].v?0:1;
if(!tree[now].ch[nxt])
{
newpoint(v,now);
tree[now].ch[nxt]=tot;
}
now=tree[now].ch[nxt];
}
}
return 0;
}
inline void insert(int v)
{
int p=build(v);//p代表插到了哪里
splay(p,root);
}
void pop(int v)
{
int deal=find(v);
if(!deal)   return ;
pointnum--;
if(tree[deal].rec>1){tree[deal].rec--;tree[deal].sum--;return ;}
if(!tree[deal].ch[0])    root=tree[deal].ch[1],tree[root].fa=0;
else
{
int le=tree[deal].ch[0];
while(tree[le].ch[1])    le=tree[le].ch[1];
splay(le,tree[deal].ch[0]);
int ri=tree[deal].ch[1];
connect(ri,le,1);connect(le,0,1);
update(le);
}
dele(deal);
}
int rank(int v)// 查询值为v的数的排名
{
int ans=0,now=root;
while(1)
{
if(tree[now].v==v)    return ans+tree[tree[now].ch[0]].sum+1;
if(now==0)  return 0;
if(v<tree[now].v)    now=tree[now].ch[0];
else                 ans+=tree[tree[now].ch[0]].sum+tree[now].rec,now=tree[now].ch[1];
}
if(now)    splay(now,root);
return 0;
}
int arank(int x)//查询排名为x的数是什么
{
int now=root;
while(1)
{
int used=tree[now].sum-tree[tree[now].ch[1]].sum;
if(x>tree[tree[now].ch[0]].sum&&x<=used)    break;
if(x<used)    now=tree[now].ch[0];
else    x=x-used,now=tree[now].ch[1];
}
splay(now,root);
return tree[now].v;
}
int lower(int v)// 小于v的最大值
{
int now=root;
int ans=-maxn;
while(now)
{
if(tree[now].v<v&&tree[now].v>ans)    ans=tree[now].v;
if(v>tree[now].v)    now=tree[now].ch[1];
else    now=tree[now].ch[0];
}
return ans;
}
int upper(int v)
{
int now=root;
int ans=maxn;
while(now)
{
if(tree[now].v>v&&tree[now].v<ans)    ans=tree[now].v;
if(v<tree[now].v)    now=tree[now].ch[0];
else    now=tree[now].ch[1];
}
return ans;
}
int a[MAXN],n,ans=0;
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
for(int i=1;i<=n;i++)
{
insert(a[i]);
int now=rank(a[i]);
if(i==1) continue;
ans=ans+i-now;
}
printf("%d",ans);
} 
View Code

## Vector六行代码过平衡树

 1 #include<cstdio>
2 #include<vector>
3 #include<algorithm>
4 using namespace std;
5 vector<int>v;
6 int n,opt,x;
7 int main()
8 {
9     v.reserve(100001);
10     scanf("%d",&n);
11     while(n--)
12     {
13         scanf("%d%d",&opt,&x);
14         if(opt==1)    v.insert(lower_bound(v.begin(),v.end(),x),x);
15         if(opt==2)    v.erase (lower_bound(v.begin(),v.end(),x));
16         if(opt==3)    printf("%d\n",lower_bound(v.begin(),v.end(),x)-v.begin()+1);
17         if(opt==4)    printf("%d\n",v[x-1]);
18         if(opt==5)    printf("%d\n",v[lower_bound(v.begin(),v.end(),x)-v.begin()-1]);
19         if(opt==6)    printf("%d\n",v[upper_bound(v.begin(),v.end(),x)-v.begin()]);
20     }
21     return 0;
22 }

Vector是个好东西，

posted @ 2017-11-05 20:23  自为风月马前卒  阅读(1948)  评论(12编辑  收藏  举报