题目
http://www.lydsy.com/JudgeOnline/problem.php?id=3289
题解
实际上就是求区间逆序对个数,第一次写树状数组求逆序对,不过感觉还是比归并排序好些。(其实感觉归并排序比较难写),因为有很多询问,所以离线搞,然后用莫队算法(第一次写莫队,感觉好神奇,还不很明白复杂度的保证)。
还有不能偷懒啊,,我感觉这份代码刚写完的时候应该有10+处bug
代码
/**************************************************************
Problem: 3289
User: QWsin
Language: C++
Result: Accepted
Time:8864 ms
Memory:3456 kb
****************************************************************/
// QWsin
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=50000+10;
const int maxa=50000+10;
inline int read()
{
int ret=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
return ret;
}
int n,m,a[maxn],sz[maxn];
ll C[maxn],ans[maxn];
struct Ask{
int l,r,kid,id;
inline void input(int i){
l=read();r=read();id=i;
}
bool operator <(const Ask &rhs)const{
if(kid!=rhs.kid) return kid<rhs.kid;
return r<rhs.r;
}
}ask[maxa];
int cmp(Ask a,Ask b){return a.l<b.l;}
#define lowbit(x) ((x)&(-x))
inline void updata(int p,int x){
for(;p<=n;p+=lowbit(p)) C[p]+=x;
}
inline ll query(int p)
{
ll ret=0;
for(;p;p-=lowbit(p)) ret+=C[p];
return ret;
}
int id[maxn];
int main()
{
int N;cin>>N;
for(int i=1;i<=N;i++) sz[i]=a[i]=read();
sort(sz+1,sz+N+1);
n=unique(sz+1,sz+N+1)-sz-1;
for(int i=1;i<=N;i++) id[i]=lower_bound(sz+1,sz+n+1,a[i])-sz;
cin>>m;
for(int i=1;i<=m;i++) ask[i].input(i);
sort(ask+1,ask+m+1,cmp);
int k=sqrt(m);
for(int i=1;i<=m;i++) ask[i].kid=(i-1)/k+1;
sort(ask+1,ask+m+1);
int L=ask[1].l,R=ask[1].r;
ll Ans=0;
for(int i=ask[1].l;i<=ask[1].r;i++)
{
Ans+=query(n)-query(id[i]);
updata(id[i],1);
}
ans[ask[1].id]=Ans;
for(int i=2;i<=m;i++)
{
int r=ask[i].r,l=ask[i].l;
while(R<r)
{
Ans+=query(n)-query(id[++R]);
updata(id[R],1);
}
while(R>r)
{
Ans-=query(n)-query(id[R]);
updata(id[R--],-1);
}
while(L<l)
{
Ans-=query(id[L]-1);
updata(id[L++],-1);
}
while(L>l)
{
Ans+=query(id[--L]-1);
updata(id[L],1);
}
ans[ask[i].id]=Ans;
}
for(int i=1;i<=m;i++)
printf("%lld\n",ans[i]);
return 0;
}

本文介绍了一种使用树状数组求解区间逆序对的方法,并结合莫队算法处理多个查询请求。通过实例讲解了如何实现这一算法,并分享了作者在编写过程中的心得与调试经验。
1196

被折叠的 条评论
为什么被折叠?



