BZOJ3787 gty的文艺妹子序列 【树状数组】【分块】
题目分析:
首先这种乱七八糟的题目就分块。然后考虑逆序对的统计。
一是块内的,二是块之间的,三是一个块内一个块外,四是都在块外。
令分块大小为$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的文艺妹子序列 【树状数组】【分块】的更多相关文章
- BZOJ3787:Gty的文艺妹子序列(分块,树状数组)
Description Autumn终于会求区间逆序对了!Bakser神犇决定再考验一下他,他说道: “在Gty的妹子序列里,某个妹子的美丽度可也是会变化的呢.你还能求出某个区间中妹子们美丽度的逆序对 ...
- BZOJ3787 : Gty的文艺妹子序列
将序列分成$\sqrt{n}$块,预处理出每两块之间的逆序对数,以及ap[i]表示前i块内数字出现次数的树状数组 预处理:$O(n\sqrt{n}\log n)$ 修改时,ap[i]可以在$O(\sq ...
- 【分块】【树状数组】bzoj3787 Gty的文艺妹子序列
题解懒得自己写了,Orz一发wangxz神犇的: http://bakser.gitcafe.com/2014/12/04/bzoj3787-Gty%E7%9A%84%E6%96%87%E8%89%B ...
- BZOJ 3787: Gty的文艺妹子序列
3787: Gty的文艺妹子序列 Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 186 Solved: 58[Submit][Status][Dis ...
- BZOJ_2141_排队_树状数组+分块
BZOJ2141_排队_树状数组+分块 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了 ...
- 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分
题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...
- bzoj4553 [Tjoi2016&Heoi2016]序列 树状数组(区间最大值)+cqd
[Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1006 Solved: 464[Submit][ ...
- Wannafly Winter Camp 2020 Day 7A 序列 - 树状数组
给定一个全排列,对于它的每一个子序列 \(s[1..p]\),对于每一个 \(i \in [1,p-1]\),给 \(s[i],s[i+1]\) 间的每一个值对应的桶 \(+1\),求最终每个桶的值. ...
- HDU3887(树dfs序列+树状数组)
Counting Offspring Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- C#(.NET) HMAC SHA256实现
HMAC SHA256的实现比较简单,可以用多种语言实现,下面我用C#语言实现,一种结果是居于BASE64,另外一种是居于64位. C# HMAC SHA256 (Base64) using Syst ...
- Jmeter(三十七)循环控制器+交替控制器+事务控制器 完美实现接口字段参数化校验
我们在做接口自动化的时候,常常因为无法灵活的的校验接口字段而烦恼.不能自动校验接口字段的脚本,也就不能称之为接口自动化.因此,我设计了一套组合式的控制器,可以完美的解决这个问题 1:首先我们需要在本地 ...
- IP判断
题目描述 在基于Internet的程序中,我们常常需要判断一个IP字符串的合法性. 合法的IP是这样的形式: A.B.C.D 其中A.B.C.D均为位于[0, 255]中的整数.为了简单起见,我们规定 ...
- Jmeter之发送请求入参必须使用编码格式、Jmeter之发送Delete请求可能入参需要使用编码格式
这里的其中一个属性值必须要先编码再传参才可以,具体可以通过抓包分析观察:
- 【Python3练习题 025】 一个数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同
[Python练习题 025] 一个5位数,判断它是不是回文数.即12321是回文数,个位与万位相同,十位与千位相同 x = input('请输入任意位数的数字:') if x == x[::-1]: ...
- maven用框架编写网页运行出现HTTP Status 500 - Unable to compile class for JSP
利用maven整合框架的时候,通过浏览器访问时,如果出现 HTTP 500-Unable to compile class for JSP 的错误,应该怎么解决呢? 之前在网上看了好多人的解决方案. ...
- MyEclipse10 复制之前的项目部署到tomcat时项目名称对不上,还是复制前的项目名称,哪里修改设置
工程 -- 右键属性 -- Myeclispse -- web修改一下发布名字就可以了.
- 11 The superlative
1 最高级用来表明三个或更多事物之间的关系.最高级是通过在形容词之前加 "the" 并在之后加 "-est",或在形容词之前加 "the most&q ...
- Linux 查询oracle错误日志&警告日志
1 通过命令查看错误日志目录:show parameter background_dump_dest /usr/oracle/app/diag/rdbms/orcl/orcl/trace 2 根据 ...
- [官网]Red Hat Enterprise Linux Release Dates
Red Hat Enterprise Linux Release Dates https://access.redhat.com/articles/3078 The tables below list ...