首页 > 代码库 > BZOJ 2141 排队 分块+树状数组
BZOJ 2141 排队 分块+树状数组
题目大意:给定一个序列,m次交换两个数,求初始逆序对数及每次交换后的逆序对数
首先离散化,分块,对于每块建立一个树状数组,保存这个块中的所有元素
然后对于每个询问(x,y) (x<y) 两侧的数是没有影响的,区间(x,y)的数a[i]讨论如下:
a[i]<a[x] --ans
a[i]>a[x] ++ans
a[i]<a[y] ++ans
a[i]>a[y] --ans
然后对于块中的树状数组处理,块外的暴力
注意此题元素有重复 亲测可信
RANK5吓尿0.0 为何块套树要比树套树还快……
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 20200 using namespace std; int n,m,ans,tot,block,a[M]; pair<int,int>b[M]; int pre[M],cnt[200][M]; void Update(int c[],int x) { for(;x<=n;x+=x&-x) ++c[x]; } void Downdate(int c[],int x) { for(;x<=n;x+=x&-x) --c[x]; } int Get_Ans(int c[],int x) { int re=0; for(;x;x-=x&-x) re+=c[x]; return re; } int main() { int i,j,x,y; cin>>n; for(i=1;i<=n;i++) scanf("%d",&b[i].first),b[i].second=i; sort(b+1,b+n+1); for(i=1;i<=n;i++) { if(b[i].first!=b[i-1].first) ++tot; a[b[i].second]=tot; } for(i=n;i;i--) ans+=Get_Ans(pre,a[i]-1),Update(pre,a[i]); block=static_cast<int>(sqrt(n)+1e-7); for(i=1;i<=n;i++) Update(cnt[(i-1)/block],a[i]); cout<<ans<<endl; cin>>m; for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); if(x>y) swap(x,y); //查询(x,y)区间内有多少个数比a[x]和a[y]小 int b1=(x-1)/block+1; int b2=(y-1)/block-1; if(b1<=b2) { for(j=b1;j<=b2;j++) { ans-=Get_Ans(cnt[j],a[x]-1); ans+=Get_Ans(cnt[j],n)-Get_Ans(cnt[j],a[x]); ans+=Get_Ans(cnt[j],a[y]-1); ans-=Get_Ans(cnt[j],n)-Get_Ans(cnt[j],a[y]); } for(j=x+1;j<=b1*block;j++) { if(a[j]<a[x]) --ans; if(a[j]>a[x]) ++ans; if(a[j]<a[y]) ++ans; if(a[j]>a[y]) --ans; } for(j=(b2+1)*block+1;j<y;j++) { if(a[j]<a[x]) --ans; if(a[j]>a[x]) ++ans; if(a[j]<a[y]) ++ans; if(a[j]>a[y]) --ans; } } else { for(j=x+1;j<=y-1;j++) { if(a[j]<a[x]) --ans; if(a[j]>a[x]) ++ans; if(a[j]<a[y]) ++ans; if(a[j]>a[y]) --ans; } } if(a[x]<a[y]) ++ans; else if(a[x]>a[y]) --ans; printf("%d\n",ans); Downdate(cnt[(x-1)/block],a[x]); Downdate(cnt[(y-1)/block],a[y]); swap(a[x],a[y]); Update(cnt[(x-1)/block],a[x]); Update(cnt[(y-1)/block],a[y]); } }
BZOJ 2141 排队 分块+树状数组
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。