您的位置:首页 > 其它

bzoj 2141: 排队

2016-08-15 10:38 246 查看

2141: 排队

Description

排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。

Input

第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi¬,表示交换位置ai与位置bi的小朋友。

Output

输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。

Sample Input

【样例输入】

3

130 150 140

2

2 3

1 3

Sample Output

1

0

3

【样例说明】

未进行任何操作时,(2,3)满足条件;

操作1结束后,序列为130 140 150,不存在满足i<j且hi>hj的(i,j)对;

操作2结束后,序列为150 140 130,(1,2),(1,3),(2,3)共3对满足条件的(i,j)。

【数据规模和约定】

对于100%的数据,1≤m≤2*103,1≤n≤2*104,1≤hi≤109,ai≠bi,1≤ai,bi≤n。

题解:

一道动态逆序对的题。

对于交换,拆成两个删除,两个插入,注意一开始要把所有数插入。。然后直接上cdq分治。

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=20005;
const int M=2005;
struct node
{
int a,id;
}A
;
struct Node
{
int a,b,c,id,No;
}p[(M<<2)+N],q[(M<<2)+N];
int n,m,Q,tot,i,k,x,y,h
,t
,ans[M];
inline void read(int &v){
char ch,fu=0;
for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
if(ch=='-') fu=1, ch=getchar();
for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
if(fu) v=-v;
}
bool cmp(const node&x,const node&y)
{
return x.a<y.a;
}
bool Cmp(const Node&x,const Node&y)
{
if(x.a!=y.a) return x.a<y.a;
return x.b<y.b;
}
void update(int x,int y)
{
while(x<=k) t[x]+=y,x+=x&-x;
}
int solve(int x)
{
int ans=0;
while(x) ans+=t[x],x-=x&-x;
return ans;
}
void add(int x,int y,int z,int Q)
{
p[++tot].id=tot;p[tot].No=Q;
p[tot].a=x;p[tot].b=y;p[tot].c=z;
}
void solve(int l,int r)
{
if(l==r) return;
int mid=(l+r)>>1,i;
for(i=l;i<=r;i++)
{
if(p[i].id<=mid) update(p[i].b,p[i].c);
if(p[i].id>mid) ans[p[i].No]+=p[i].c*(solve(k)-solve(p[i].b));
}
for(i=l;i<=r;i++)
if(p[i].id<=mid) update(p[i].b,-p[i].c);
for(i=r;i>=l;i--)
{
if(p[i].id<=mid) update(p[i].b,p[i].c);
if(p[i].id>mid) ans[p[i].No]+=p[i].c*solve(p[i].b-1);
}
for(i=l;i<=r;i++)
if(p[i].id<=mid) update(p[i].b,-p[i].c);
int L=l,R=mid+1;
for(i=l;i<=r;i++)
if(p[i].id<=mid) q[L++]=p[i];else q[R++]=p[i];
for(i=l;i<=r;i++) p[i]=q[i];
solve(l,mid);solve(mid+1,r);
}
int main()
{
read(n);
for(i=1;i<=n;i++) read(A[i].a),A[i].id=i;
sort(A+1,A+n+1,cmp);
k=1;h[A[1].id]=1;
for(i=2;i<=n;i++)
{
if(A[i].a!=A[i-1].a) k++;
h[A[i].id]=k;
}
for(i=1;i<=n;i++) p[++tot].id=tot,p[tot].a=i,p[tot].b=h[i],p[tot].c=1;
read(m);
for(i=1;i<=m;i++)
{
read(x),read(y);
add(x,h[x],-1,++Q);add(y,h[y],-1,Q);
add(x,h[y],1,Q);add(y,h[x],1,Q);
swap(h[x],h[y]);
}
sort(p+1,p+tot+1,Cmp);
solve(1,tot);
printf("%d\n",ans[0]);
for(i=1;i<=m;i++) ans[i]+=ans[i-1],printf("%d\n",ans[i]);
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: