总时间复杂度不超过O(n√nlogn)
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 50500
#define SQRT_M 250
using namespace std;
int n,m,block,ans;
int a[M],b[M];
int f[SQRT_M][SQRT_M];
//f[i][i]表示第i块内部的逆序对数
//f[i][j](i<j)表示第i块中的元素与第j块中的元素之间的逆序对数
int g[SQRT_M][SQRT_M];
//g[i][j](i<=j)表示第i块中的元素与第i~j块中的元素之间的逆序对数
//第一维暴力第二维树状数组前缀和
//向上修改向下查询
int equals[SQRT_M][M];
int smaller[SQRT_M][M];
/*
equals[i][j]表示前i块之内j的数量 直接暴力
smaller[i][j]表示前i块之内小于等于j的数的数量 向上修改向下查询
第一维暴力第二维树状数组
*/
int l[SQRT_M],r[SQRT_M],belong[M];
int Merge_Sort(int l,int r,int b[]=::b)
{
static int c[M];
int i,mid=l+r>>1,re=0;
if(l==r)
return 0;
re=Merge_Sort(l,mid,b)+Merge_Sort(mid+1,r,b);
int l1=l,l2=mid+1;
for(i=l;i<=r;i++)
{
if( b[l1]<=b[l2] && l1<=mid || l2>r )
c[i]=b[l1++],re+=l2-mid-1;
else
c[i]=b[l2++];
}
memcpy( b+l , c+l , sizeof(b[0])*(r-l+1) );
return re;
}
void Update(int c[],int x,int y,int limit)
{
for(;x<=limit;x+=x&-x)
c[x]+=y;
}
int Get_Ans(int c[],int x)
{
int re=0;
for(;x;x-=x&-x)
re+=c[x];
return re;
}
void Modify(int x,int y)
{
int i,j,_block=belong[x],temp;
for(i=1;i<_block;i++)
{
temp=upper_bound(b+l[i],b+r[i]+1,y)-upper_bound(b+l[i],b+r[i]+1,a[x]);
Update(g[i],_block,-temp,(n-1)/block+1);
}
for(i=_block+1;(i-1)*block+1<=n;i++)
{
temp=lower_bound(b+l[i],b+r[i]+1,y)-lower_bound(b+l[i],b+r[i]+1,a[x]);
Update(g[_block],i,temp,(n-1)/block+1);
}
memcpy(b+l[_block],a+l[_block],sizeof(b[0])*(r[_block]-l[_block]+1) );
b[x]=y;
temp=Merge_Sort(l[_block],r[_block]);
//重构b数组
Update(g[_block],_block,temp-f[_block][_block],(n-1)/block+1);
f[_block][_block]=temp;
//修改f[i][i]和g[i][~]
for(i=_block;(i-1)*block+1<=n;i++)
{
equals[i][a[x]]--,equals[i][y]++;
Update(smaller[i],a[x],-1,n);
Update(smaller[i],y,1,n);
}
//修改euqal和smaller数组
a[x]=y;
//修改a数组
}
int Query(int x,int y)
{
static int c[M];
int i,top=0,re=0;
if(belong[y]-belong[x]<=1)
{
memcpy(c+x,a+x,sizeof(a[0])*(y-x+1) );
return Merge_Sort(x,y,c);
}
for(i=belong[x]+1;i<belong[y];i++)
re+=Get_Ans(g[i],belong[y]-1);
//BB
for(i=x;i<=r[belong[x]];i++)
{
re+=Get_Ans(smaller[belong[y]-1],a[i])-Get_Ans(smaller[belong[x]],a[i])-
( equals[belong[y]-1][a[i]] - equals[belong[x]][a[i]] );
c[++top]=a[i];
}
//AB
for(i=l[belong[y]];i<=y;i++)
{
re+=r[belong[y]-1]-r[belong[x]]-
( Get_Ans(smaller[belong[y]-1],a[i])-Get_Ans(smaller[belong[x]],a[i]) );
c[++top]=a[i];
}
//BC
return re+Merge_Sort(1,top,c);
//AA+AC+CC
}
int main()
{
int i,j,k;
int p,x,y;
cin>>n;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
block=static_cast<int>(sqrt(n)+1e-7);
for(i=1;i<=n;i++)
{
belong[i]=(i-1)/block+1;
b[i]=a[i];
}
for(i=1;(i-1)*block+1<=n;i++)
{
l[i]=(i-1)*block+1,r[i]=min(i*block,n);
f[i][i]=Merge_Sort(l[i],r[i]);
}
//预处理块和f[i][i]
for(i=1;(i-1)*block+1<=n;i++)
for(j=i+1;(j-1)*block+1<=n;j++)
{
int p=l[j];
for(k=l[i];k<=r[i];k++)
{
for(;p<=r[j]&&b[p]<b[k];p++);
f[i][j]+=p-l[j];
}
}
for(i=1;(i-1)*block+1<=n;i++)
for(j=i;(j-1)*block+1<=n;j++)
Update(g[i],j,f[i][j],(n-1)/block+1);
//预处理f数组和g数组
for(i=1;i<=n;i++)
for(j=belong[i];j<=(n-1)/block+1;j++)
{
equals[j][a[i]]++;
Update(smaller[j],a[i],1,n);
}
//预处理equals数组和smaller数组
cin>>m;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&p,&x,&y);
x^=ans;y^=ans;
if(p==1)
Modify(x,y);
else
printf("%d\n", ans=Query(x,y) );
}
}原文:http://blog.csdn.net/popoqqq/article/details/41699991