离散化,分块。

预处理出:ans[i][j] 第i块到第j块的逆序对数。

f[i][j] 第1~i块中大于j的数的个数。

g[i][j] 第1~j块中小于j的数的个数。

每次询问时对于整块部分可以O(1)获得。

对于零散部分呢?

>在一列数的后面添加一个数,逆序对数会增加 数列中比它大的数的个数。

>在一列数的前面添加一个数,逆序对数会增加 数列中比它小的数的个数。

所以统计以上信息的时候,对于整块的部分,我们可以借由预处理的东西差分来O(1)地获得答案,零散的部分就是树状数组咯。

空间复杂度是O(n*sqrt(n))的。

时间复杂度是O(n*sqrt(n)*log(n))的。

P.S.根本不用卡常数什么的呢。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define N 50001
#define BLOCK_SIZE 250
int sz,sum,n,a[N],l[BLOCK_SIZE],r[BLOCK_SIZE],D[N],f[BLOCK_SIZE][BLOCK_SIZE];
int Less[BLOCK_SIZE][N],More[BLOCK_SIZE][N],b[N],en,m,x,y,num[N],ans;
struct Point{int v,p;}t[N];
bool operator < (const Point &a,const Point &b){return a.v<b.v;}
int Res,Num;char C,CH[];
inline int G()
{
Res=;C='*';
while(C<''||C>'')C=getchar();
while(C>=''&&C<=''){Res=Res*+(C-'');C=getchar();}
return Res;
}
inline void P(int x)
{
Num=;if(!x){putchar('');puts("");return;}
while(x>)CH[++Num]=x%,x/=;
while(Num)putchar(CH[Num--]+);
puts("");
}
void add(int p,const int &v) {while(p<=n) {D[p]+=v; p+=(p&(-p));}}
int getsum(int p) {int res=; while(p) {res+=D[p]; p-=(p&(-p));} return res;}
void makeblock()
{
sz=sqrt(n); if(!sz) sz=;
for(sum=;sum*sz<n;sum++)
{
l[sum]=r[sum-]+;
r[sum]=sum*sz;
for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
}
l[sum]=r[sum-]+;
r[sum]=n;
for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
}
void LiSan()
{
sort(t+,t+n+); a[t[].p]=++en;
for(int i=;i<=n;i++)
{
if(t[i].v!=t[i-].v) en++;
a[t[i].p]=en;
}
}
void init_each_ans()
{
for(int i=;i<=sum;i++)
{
memset(D,,sizeof(D)); int pos=,res=;
for(int j=i;j<=sum;j++)
{
for(int k=l[j];k<=r[j];k++)
{
pos++;
add(a[k],);
res+=(pos-getsum(a[k]));
}
f[i][j]=res;
}
} memset(D,,sizeof(D));
}
void init_sum()
{
memcpy(b,a,sizeof(b));
for(int i=;i<=sum;i++)
{
sort(b+l[i],b+r[i]+);
memcpy(More[i],More[i-],sizeof(More[i]));
memcpy(Less[i],Less[i-],sizeof(Less[i]));
for(int j=;j<=en;j++)
{
More[i][j]+=(b+r[i]+-upper_bound(b+l[i],b+r[i]+,j));
Less[i][j]+=(lower_bound(b+l[i],b+r[i]+,j)-(b+l[i]));
}
}
}
int getMore(const int &L,const int &R,const int &v){return More[R][v]-More[L-][v];}
int getLess(const int &L,const int &R,const int &v){return Less[R][v]-Less[L-][v];}
int main()
{
n=G();
for(int i=;i<=n;i++)
{
t[i].v=G();
t[i].p=i;
}
LiSan(); makeblock(); init_each_ans(); init_sum();
m=G();
for(int j=;j<=m;j++)
{
x=G(); y=G(); x^=ans; y^=ans;
if(num[x]+>=num[y])
{
int pos=; ans=;
for(int i=x;i<=y;i++)
{
pos++;
add(a[i],);
ans+=(pos-getsum(a[i]));
}
for(int i=x;i<=y;i++) add(a[i],-);
P(ans);
}
else
{
int pos=r[num[x]]-x+; ans=f[num[x]+][num[y]-];
for(int i=r[num[x]];i>=x;i--)
{
ans+=(getLess(num[x]+,num[y]-,a[i])+getsum(a[i]-));
add(a[i],);
}
for(int i=l[num[y]];i<=y;i++)
{
pos++;
add(a[i],);
ans+=(pos-getsum(a[i])+getMore(num[x]+,num[y]-,a[i]));
}
for(int i=x;i<=r[num[x]];i++) add(a[i],-);
for(int i=l[num[y]];i<=y;i++) add(a[i],-);
P(ans);
}
}
return ;
}

最新文章

  1. Git(最基本使用远程仓库:github)-V1.0
  2. Magento学习第一课——目录结构介绍
  3. SOCKS 5协议详解(转)
  4. 一步一步教你编写与搭建自动化测试框架——python篇
  5. JVM常见的七种垃圾收集器的简单比较
  6. [SQL]不知道
  7. Java 8怎么了:局部套用vs闭包
  8. HDOJ --- Super Jumping! Jumping! Jumping!
  9. OCR文字识别帮助录入文字信息
  10. 【JAVAWEB学习笔记】01_HTML
  11. spring data redis template GenericJackson2JsonRedisSerializer的使用
  12. C++版 - 剑指offer面试题38:数字在已排序数组中出现的次数
  13. springboot情操陶冶-web配置(四)
  14. 从设计模式的角度看Java程序优化
  15. JavaScript数据类型,构造函数
  16. mysql导入自定义函数不成功的解决方法
  17. C# Interview Question 1
  18. 【Learning】一步步地解释Link-cut Tree
  19. java基础----&gt;java中nio的使用(一)
  20. 突破防盗链机制:使用referrer-killer

热门文章

  1. Kafka自我学习3-Scalable
  2. 线程 ManualResetEvent 类
  3. javascript提示抖动实现方法
  4. 浅析 nth-child(n) 和 nth-of-type(n)
  5. mysql 基本操作练习
  6. jzoj2701 【GDKOI2012模拟02.01】矩阵
  7. Python标准库——collections模块的Counter类
  8. nginx、apache、tomcat的区别
  9. SSH Secure Shell 无法登录:server responded &quot;algorithm negotiation failed”
  10. python常用内置函数整理