题目分析:

首先这种乱七八糟的题目就分块。然后考虑逆序对的统计。

一是块内的,二是块之间的,三是一个块内一个块外,四是都在块外。

令分块大小为$S$。

块内的容易维护,单次维护时间是$O(S)$。

块之间的有两种维护方法,一种是在块内维持有序,那么修改的时候进行一次插排,查询的时候枚举每一块,然后二分查找;另一种是利用下面所述的另一个数组来做块内统计。第一种方法的时间是$O(S+\frac{n}{S}\log S)$;第二种是$O(\frac{n}{S}logn)$.这里我们需要用树状数组维护,但是树状数组带的$\log$与查找是独立的。

一个在块内一个在块外的通过枚举块外的,然后利用数组$f[i][j]$记录$1 \sim i$块小于等于$j$的数的个数,这里用树状数组维护前缀和。时间复杂度是$O(S \log n)$.

最后一部分单独提取出来求逆序对,时间$O(SlogS)$.

那么$O(Slogn) = O(\frac{n}{S}logn)$可以解得$S = O(\sqrt{n})$.

所以这样做的时间复杂度是$O(n\sqrt{n}logn)$

代码:

 #include<bits/stdc++.h>
using namespace std; const int srt = ;
const int maxn = ; int n,m;
int c[srt+][maxn],inside[maxn],con[srt+][srt+];
int a[maxn],ord[maxn]; int lowbit(int x){return x&-x;} void add(int now,int dr,int om){while(now <= n)c[om][now]+=dr,now+=lowbit(now);}
int query(int now,int om){
int ans = ;
while(now){ans += c[om][now]; now -= lowbit(now);}
return ans;
}
void Add(int now,int dr,int om){while(now<=n/srt+){con[om][now]+=dr;now += lowbit(now);}}
int Query(int now,int om){
int ans = ;
while(now){ans += con[om][now]; now -= lowbit(now);}
return ans;
} void read(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&m);
} void init(){
for(int i=,cnt=;i<=n;i+=srt,cnt++){
memset(c[],,sizeof(c[]));
for(int j=srt-;j>=;j--){
if(j+i > n) continue;
inside[cnt] += query(a[i+j]-,);
add(a[i+j],,);
}
}
for(int i=;(i-)*srt+<=n;i++){
memset(c[],,sizeof(c[]));
for(int j=(i-)*srt+;j<=min(n,i*srt);j++) add(a[j],,);
for(int j=i+;(j-)*srt+<=n;j++){
for(int k=(j-)*srt+;k<=min(n,j*srt);k++)
con[i][j] += query(n,)-query(a[k],);
}
}
for(int i=;(i-)*srt+<=n;i++){
int j; for(j=i+;(j-)*srt+<=n;j++);
for(;j>i;j--){ int z = con[i][j]; con[i][j] = ; Add(j,z,i); }
for(int j=(i-)*srt+;j<=min(n,i*srt);j++){
for(int k=i;(k-)*srt+<=n;k++) add(a[j],,k);
}
}
} void work(){
int lastans = ;memset(c[],,sizeof(c[]));
for(int i=;i<=m;i++){
int pv; scanf("%d",&pv);
if(pv == ){
int l,r; scanf("%d%d",&l,&r); l^=lastans; r^=lastans;
if(r-l < srt){
int ans = ;
for(int j=r;j>=l;j--){ans += query(a[j]-,);add(a[j],,);}
for(int j=r;j>=l;j--){add(a[j],-,);}
printf("%d\n",ans);lastans = ans;
continue;
}
int st=,ed=;
while((st-)*srt+ < l)st++; while(ed*srt<=r)ed++;ed--;
int ans = ; for(int j=st;j<=ed;j++)ans += inside[j];
for(int j=st;j<=ed;j++){ans += Query(ed,j);}
for(int j=l;j%srt!=;j++)ans+=query(a[j]-,ed)-query(a[j]-,st-);
for(int j=ed*srt+;j<=r;j++){
ans += (query(n,ed)-query(n,st-));
ans -= (query(a[j],ed)-query(a[j],st-));
}
for(int j=r;j>ed*srt;j--){ans += query(a[j]-,); add(a[j],,);}
for(int j=(st-)*srt;j>=l;j--){ans+=query(a[j]-,);add(a[j],,);}
for(int j=r;j>ed*srt;j--) add(a[j],-,);
for(int j=(st-)*srt;j>=l;j--) add(a[j],-,);
printf("%d\n",ans);lastans = ans;
}else{
int p,v; scanf("%d%d",&p,&v);p^=lastans,v ^= lastans;
int bel = p/srt+(p%srt!=);
for(int j=(bel-)*srt+;j<p;j++){
if(a[j] > a[p]) inside[bel]--; if(a[j] > v) inside[bel]++;
}
for(int j=p+;j<=bel*srt;j++){
if(a[j] < a[p]) inside[bel]--; if(a[j] < v) inside[bel]++;
}
for(int j=;j<bel;j++){
int z = (srt-query(a[p],j)+query(a[p],j-));
int zz = (srt-query(v,j)+query(v,j-));
Add(bel,zz-z,j);
}
for(int j=bel+;(j-)*srt+<=n;j++){
int z=query(a[p]-,j)-query(a[p]-,j-);
int r=query(v-,j)-query(v-,j-);
Add(j,r-z,bel);
}
for(int j=bel;(j-)*srt+<=n;j++){add(a[p],-,j); add(v,,j);}
a[p] = v;
}
}
} int main(){
read();
init();
work();
return ;
}

BZOJ3787 gty的文艺妹子序列 【树状数组】【分块】的更多相关文章

  1. BZOJ3787:Gty的文艺妹子序列(分块,树状数组)

    Description Autumn终于会求区间逆序对了!Bakser神犇决定再考验一下他,他说道: “在Gty的妹子序列里,某个妹子的美丽度可也是会变化的呢.你还能求出某个区间中妹子们美丽度的逆序对 ...

  2. BZOJ3787 : Gty的文艺妹子序列

    将序列分成$\sqrt{n}$块,预处理出每两块之间的逆序对数,以及ap[i]表示前i块内数字出现次数的树状数组 预处理:$O(n\sqrt{n}\log n)$ 修改时,ap[i]可以在$O(\sq ...

  3. 【分块】【树状数组】bzoj3787 Gty的文艺妹子序列

    题解懒得自己写了,Orz一发wangxz神犇的: http://bakser.gitcafe.com/2014/12/04/bzoj3787-Gty%E7%9A%84%E6%96%87%E8%89%B ...

  4. BZOJ 3787: Gty的文艺妹子序列

    3787: Gty的文艺妹子序列 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 186  Solved: 58[Submit][Status][Dis ...

  5. BZOJ_2141_排队_树状数组+分块

    BZOJ2141_排队_树状数组+分块 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了 ...

  6. 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分

    题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...

  7. bzoj4553 [Tjoi2016&Heoi2016]序列 树状数组(区间最大值)+cqd

    [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1006  Solved: 464[Submit][ ...

  8. Wannafly Winter Camp 2020 Day 7A 序列 - 树状数组

    给定一个全排列,对于它的每一个子序列 \(s[1..p]\),对于每一个 \(i \in [1,p-1]\),给 \(s[i],s[i+1]\) 间的每一个值对应的桶 \(+1\),求最终每个桶的值. ...

  9. HDU3887(树dfs序列+树状数组)

    Counting Offspring Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

随机推荐

  1. flink1.7自定义source实现

    flink读取source data 数据的来源是flink程序从中读取输入的地方.我们可以使用StreamExecutionEnvironment.addSource(sourceFunction) ...

  2. 01 前言/基础设施 - DevOps之路

    01 前言/基础设施 - DevOps之路 文章Github地址,欢迎start:https://github.com/li-keli/DevOps-WiKi 简介 基础架构采用DevOps设计思想, ...

  3. python的循环和选择

    一.python的选择结构: python的选择结构有两种选择结构一种是单选择(if...else)另一种则是多选择结构(if ...elif...elif) 下面用代码来实现: 1.if....el ...

  4. CRM系统(第三部分)

      阅读目录 1.销售与客户的表结构 2.公共客户池 3.确认跟进 4.我的客户 5.code 1.销售与客户的表结构 1.公共客户与我的客户 ---公共客户(公共资源) 1.没有报名 2.3天没有跟 ...

  5. 福州大学软件工程1816 | W班 第5次作业成绩排名

    写在前面 汇总成绩排名链接 1.作业链接 第五次作业--项目选题报告(团队) 2.评分准则 本次作业映射总分为100分+贡献度得分,由以下部分组成: 选题报告内容(10分) 本组评审表设计(5分) 现 ...

  6. 敏捷开发、DevOps相关书籍——书单

    自己瞎整理的一些书单,都是豆瓣评分比较高的书,可以作为选择的一个参考. 书名 豆瓣链接 持续交付:发布可靠软件的系统方法 https://book.douban.com/subject/6862062 ...

  7. 【kindle笔记】之 《黑客微百科》-2018-6-17

    前段时间复习六级的时候,从图书馆看到一本书,然后带回来了.今天开始读.今天是2018年6月17日. 严格来讲,一本不算kindle笔记的笔记,不过广义的啃豆笔记了解一下.哈哈. 首页说到的黑客理念是: ...

  8. Git分支合并:Merge、Rebase的选择

    git代码合并:Merge.Rebase的选择 - iTech - 博客园http://www.cnblogs.com/itech/p/5188932.html Git如何将一个分支的修改同步到另一个 ...

  9. Windows激活

    最近重新安装了一下系统,我的系统是Windows10.这就出现了一个问题,如果是Windows7系统的话,可以使用网上的破解工具进行破解操作,使之成为永久破解版.但是Windows10系统,网上对于它 ...

  10. html5调用手机摄像头(图片可多选 限pc)

    html5自带的 input file=”” ,纯html5,并且不涉及到js ,就可以实现.代码如下: <input type="file" accept="im ...