思路:利用树状数组求出正序的个数,对于R[S E](数据是S<=E的。。)只要对[S E]区间中 F[S]的逆序数ans++,正序数ans--,然后对其翻转即可。
Code :
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int MAX_N=3000005;
const int MAX_S=10005;
int n,Q;
int a[MAX_N];
int Tree[MAX_S];
int Lowbit(int x);
void Update(int id,int x);
int Query(int id);
int main()
{
ios::sync_with_stdio(false);
while(cin>>n){
memset(Tree,0,sizeof(Tree));
LL ans=0;
for(int i=1;i<=n;++i)
{
cin>>a[i];
Update(a[i],1);
ans+=Query(a[i]-1);
}
cin>>Q;
char c;
int u,v;
while(Q--){
cin>>c;
if(c=='Q'){
cout<<ans<<endl;
}else{
cin>>u>>v;
++u; ++v;
int p=a[u];
if(u<v){
for(int i=u;i<=v;++i)
{
if(p>a[i]) ans++;
else if(p<a[i]) ans--;
a[i]=a[i+1];
}
}else if(u>v){
for(int i=u;i>=v;--i)
{
if(p>a[i]) ans--;
else if(p<a[i]) ans++;
a[i]=a[i-1];
}
}
a[v]=p;
}
}
}
return 0;
}
int Lowbit(int x)
{
return x&(-x);
}
void Update(int id,int x)
{
while(id<MAX_S){
Tree[id]+=x;
id+=Lowbit(id);
}
}
int Query(int id)
{
int ans=0;
while(id>0){
ans+=Tree[id];
id-=Lowbit(id);
}
return ans;
}