题意

给出n个数,要求支持单点修改和区间逆序对,强制在线。
n,m<=50000

题解

和不带修改差不多,预处理出smaller[i][j]代表前i块小于j的数的数量,但不能用f[i][j]代表第i块到第j块逆序对的数量,这样不好维护。

我们用f[i][j]代表从第i块选出一个元素与从第j块选出一个元素组成逆序对的数量,维护时最多修改根号n个f数组,查询时用前缀和起到与不带修改时f数组的作用。

其他部分和不带修改时差不多。

然后问题就解决了。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=;
int n,Block,a[N],block[N],L[],R[],tr1[][],tr[][N],ans,m;
int lowbit(int x){
return x&-x;
}
void add(int id,int x,int w){
for(int i=x;i<=n;i+=lowbit(i)){
tr[id][i]+=w;
}
}
int getsum(int id,int x){
int tmp=;
for(int i=x;i;i-=lowbit(i)){
tmp+=tr[id][i];
}
return tmp;
}
void add1(int id,int x,int w){
for(int i=x;i<=block[n];i+=lowbit(i)){
tr1[id][i]+=w;
}
}
int getsum1(int id,int x){
int tmp=;
for(int i=x;i;i-=lowbit(i)){
tmp+=tr1[id][i];
}
return tmp;
}
int main(){
scanf("%d",&n);Block=sqrt(n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
block[i]=(i-)/Block+;
if(!L[block[i]])L[block[i]]=i;
R[block[i]]=i;
}
for(int i=;i<=block[n];i++)
for(int j=L[i];j<=n;j++){
add(i,a[j],);
}
for(int i=;i<=block[n];i++){
for(int j=L[i];j<=R[i];j++){
add(,a[j],);
add1(i,i,getsum(,n)-getsum(,a[j]));
}
for(int j=R[i]+;j<=n;j++){
add1(i,block[j],getsum(,n)-getsum(,a[j]));
}
for(int j=L[i];j<=R[i];j++){
add(,a[j],-);
}
}
scanf("%d",&m);
while(m--){
int k,x,y;
scanf("%d%d%d",&k,&x,&y);
x^=ans;y^=ans;
if(k==){
for(int i=;i<=block[x]-;i++){
int size=R[i]-L[i]+;
add1(i,block[x],size-(getsum(i,y)-getsum(i+,y))-(size-(getsum(i,a[x])-getsum(i+,a[x]))));
}
for(int i=block[x]+;i<=block[n];i++){
add1(block[x],i,getsum(i,y-)-getsum(i+,y-)-(getsum(i,a[x]-)-getsum(i+,a[x]-)));
}
for(int i=L[block[x]];i<=R[block[x]];i++){
add(,a[i],);
add1(block[x],block[x],-(getsum(,n)-getsum(,a[i])));
}
for(int i=L[block[x]];i<=R[block[x]];i++){
add(,a[i],-);
}
for(int i=;i<=block[x];i++){
add(i,a[x],-);add(i,y,);
}
a[x]=y;
for(int i=L[block[x]];i<=R[block[x]];i++){
add(,a[i],);
add1(block[x],block[x],getsum(,n)-getsum(,a[i]));
}
for(int i=L[block[x]];i<=R[block[x]];i++){
add(,a[i],-);
}
}
else{
if(block[x]+>=block[y]){
ans=;
for(int i=x;i<=y;i++){
add(,a[i],);
ans+=getsum(,n)-getsum(,a[i]);
}
for(int i=x;i<=y;i++){
add(,a[i],-);
}
printf("%d\n",ans);
}
else{
ans=;
for(int i=block[x]+;i<=block[y]-;i++){
ans+=getsum1(i,block[y]-);
}
for(int i=x;i<=R[block[x]];i++){
add(,a[i],);
ans+=getsum(,n)-getsum(,a[i]);
ans+=getsum(block[x]+,a[i]-)-getsum(block[y],a[i]-);
}
for(int i=L[block[y]];i<=y;i++){
add(,a[i],);
ans+=getsum(,n)-getsum(,a[i]);
ans+=getsum(block[x]+,n)-getsum(block[y],n)-(getsum(block[x]+,a[i])-getsum(block[y],a[i]));
}
for(int i=x;i<=R[block[x]];i++){
add(,a[i],-);
}
for(int i=L[block[y]];i<=y;i++){
add(,a[i],-);
}
printf("%d\n",ans);
}
}
}
return ;
}

BZOJ 3787 Gty的文艺妹子序列(分块+树状数组+前缀和)的更多相关文章

  1. BZOJ 3787: Gty的文艺妹子序列 [分块 树状数组!]

    传送门 题意:单点修改,询问区间内逆序对数,强制在线 看到加了!就说明花了不少时间.... 如果和上题一样预处理信息,用$f[i][j]$表示块i到j的逆序对数 强行修改的话,每个修改最多会修改$(\ ...

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

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

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

    题目分析: 首先这种乱七八糟的题目就分块.然后考虑逆序对的统计. 一是块内的,二是块之间的,三是一个块内一个块外,四是都在块外. 令分块大小为$S$. 块内的容易维护,单次维护时间是$O(S)$. 块 ...

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

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

  5. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  6. BZOJ 3744 Gty的妹子序列 (分块+树状数组+主席树)

    题面传送门 题目大意:给你一个序列,多次询问,每次取出一段连续的子序列$[l,r]$,询问这段子序列的逆序对个数,强制在线 很熟悉的分块套路啊,和很多可持久化01Trie的题目类似,用分块预处理出贡献 ...

  7. 【BZOJ3744】Gty的妹子序列 分块+树状数组

    [BZOJ3744]Gty的妹子序列 Description 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzo ...

  8. BZOJ 3744 Gty的妹子序列 分块+树状数组

    具体分析见 搬来大佬博客 时间复杂度 O(nnlogn)O(n\sqrt nlogn)O(nn​logn) CODE #include <cmath> #include <cctyp ...

  9. BZOJ 4765 普通计算姬 dfs序+分块+树状数组+好题!!!

    真是道好题...感到灵魂的升华... 按dfs序建树状数组,拿前缀和去求解散块: 按点的标号分块,分成一个个区间,记录区间子树和 的 总和... 具体地,需要记录每个点u修改后,对每一个块i的贡献,记 ...

随机推荐

  1. Storm Spout

    本文主要介绍了Storm Spout,并以KafkaSpout为例,进行了说明. 概念 数据源(Spout)是拓扑中数据流的来源.一般 Spout 会从一个外部的数据源读取元组然后将他们发送到拓扑中. ...

  2. Android程序能够构建和运行,但是报以下报错,为什么?

    安卓程序写完之后能够构建和运行,但是会报以下的错误.不知道原因为何?求大神解答. 网上说的是混淆编译的原因,不过程序没有开启混淆编译. Error:warning: Ignoring InnerCla ...

  3. ASP.NET 让ajax请求webform后台方法

    $.ajax({ type: "POST", url: ".aspx/getSubjectDirection", data: JSON.stringify({ ...

  4. jq 鼠标点击跳转页面后 改变点击菜单的样式代码

    点击菜单跳转页面,然而跳转后的页面字体并没有加粗用如下代码 <div class="bg01 menu"> <img class="img01" ...

  5. 洛谷2055 [ZJOI2009]假期的宿舍

    题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...

  6. 越努力越幸运--3-日常bug修复

    提供一个so给PYTHON调用,后端发现业务处理流程不是按照方法传入的参数来跑. 查看c的代码,看了客户端没看出什么问题,查看服务端为什么会出现这样的情况,有些字段明显不是入参带过来的,跟踪服务端解析 ...

  7. WPF 列表自动换行

    原文:WPF 列表自动换行 本文告诉大家如何在 ListView 或 ListBox 使用 WrapPanel 让里面的控件自动换行 在 WPF 可以通过修改 ItemsPanel 设置使用不同的 I ...

  8. C语言中数据类型的字节数

    类型 16位 32 位 64位 char 1 1 1 short int 2 2 2 int 2 4 4 unsigned int 2 4 4 float 4 4 4 double 8 8 8 lon ...

  9. &quot;duplicate symbol for architecture i386&quot; 解决的方法

    我在写项目的过程中,碰到了这个错误,我在网上查了一下,发现这个错误的原因是,project里面有反复的类. 解决方式:找到反复的类,然后删除掉就好了. 分析一下, 如图. 能够看出, 错误类型是 du ...

  10. gcc 源代码下载地址

    ftp://mirrors-usa.go-parts.com/gcc/releases/