BZOJ 3787: Gty的文艺妹子序列

3787: Gty的文艺妹子序列

Time Limit: 50 Sec  Memory Limit: 256 MB
Submit: 186  Solved: 58
[Submit][Status][Discuss]

Description

Autumn终于会求区间逆序对了!Bakser神犇决定再考验一下他,他说道:
 
“在Gty的妹子序列里,某个妹子的美丽度可也是会变化的呢。你还能求出某个区间
 
中妹子们美丽度的逆序对数吗?当然,为了方便,这次我们规定妹子们的美丽度在
 
[1,n]中。仍然强制在线。”
 
Autumn需要你的帮助。
 
给定一个正整数序列a(1<=ai<=n),支持单点修改,对于每次询问,输出al...ar中
 
的逆序对数,强制在线。

 

Input

第一行包括一个整数n(1<=n<=50000),表示数列a中的元素数。
 
第二行包括n个整数a1...an(1<=ai<=n)。
 
接下来一行包括一个整数m(1<=m<=50000),表示操作的个数。
 
接下来m行,每行包括3个整数。
 
0 L R (1<=L<=R<=n) 询问[L,R]中的逆序对数。
 
1 p v (1<=p<=n,1<=v<=n) 将p位置的数修改为v。
 
L,R,p,v 都需要异或上一次的答案,保证异或之后的值是合法的。
 
保证涉及的所有数在int内。

 

Output

对每个询问,单独输出一行,表示al...ar中的逆序对数。对每个询问,单独输出一行,表示al...ar中的逆序对数。

 

Sample Input

10
1 7 5 6 9 4 9 4 4 7
10
0 4 6
0 5 8
0 1 10
1 25 19
0 19 25
1 14 4
0 12 12
0 2 5
1 8 7
1 1 10

Sample Output

2
3
16
13
0
2

HINT

 

Source

[Submit][Status][Discuss]

 

又是分块,然后LincHpin给出了一个和PoPoQQQ很像的做法,我则选择另外的一种。客观地讲,两者的理论复杂度都是$O(N\sqrt{N}log(N))$,代码难度也都那样(不会太简单)。

 

大爷的方法

预处理

先分块,预处理块内逆序对,维护块内权值。然后G[i][j]表示第i块和第j块形成的逆序对,即统计了所有一个在第i块,一个在第j块的逆序对,这个也是一开始预处理一下,第一维暴力,第二维树状数组维护。因为妹子颜值的大小不会太大,所以可以开个数组E[i][j]表示前i块内颜值为j的妹子个数,简单与处理一下就有了。还需要用S[i][j]表示前i块内颜值小于等于j的妹子数量,类似于E[i][j]的前缀和,第一维暴力,第二维树状数组维护。

查询 

查询区间分为两种:左右边界处的零碎妹子,中间块内的大把妹子。

零碎妹子内部暴力,和中间妹子产生的逆序对直接通过E,S数组求出来,复杂度$O(\sqrt{N}log(N))$。

中间大把妹子也属于多个分块,先加上每个分块内部的逆序对,再加上$\sum{G[i][j]}$,这个第一维暴力枚举,第二维在树状数组中查询,复杂度$O(\sqrt{N}log(N))$。

修改

修改一个妹子的颜值时,块内逆序对的变化可以直接对块进行暴力重做,复杂度$O(\sqrt{N}log(N))$,改变该块的权值线段树,$O(log(N))$。

考虑对G[i][j]的影响,只有$O(\sqrt{N})$个G[i][j]包含该妹子(即该妹子所在的块),因为每个块维护了权值线段树,单个改动是$O(log(N))$的,所以总复杂度$O(\sqrt{N}log(N))$。

考虑对E[i][j]的影响,只有$O(\sqrt{N})$个E[i][j]需要改动,单个改动是$O(1)$的,总的复杂度是$O(\sqrt{N})$。

考虑对S[i][j]的影响,只有$O(\sqrt{N})$个E[i][j]需要改动,单个改动是$O(log(N))$的,总的复杂度是$O(\sqrt{N}log(N))$。

 

蒟蒻(小生)的方法


基本的分块还是和大爷一样的,G[i][j]表示从第i块到第j块的区间内的逆序对数,用树状数组套主席树维护区间权值分布并支持单点修改。

查询就是直接取出中间的大把妹子,从G[i][j]中查询答案,暴力扫描两侧的零碎妹子,用权值主席树处理其和大把妹子产生的逆序对。

修改主要是考虑到G[i][j]的问题。大爷起初认为G[i][j]一共有N个,所以不能快速修改。但是发现可以这么考虑:

设修改妹子在块k

所有i<k的G都会被修改,暴力枚举一下i的话,对于一个i,只有满足j>k的G[i][j]才会被累加上i到k这一区间产生的改变量,对于一个i这是个区间加问题。

所有j>k的G都会被修改,暴力枚举一下j的话,对于一个j,只有满足i<k的G[i][j]才会被累加上k到j这一区间产生的改变量,对于一个j这是个区间加问题。

所以分开维护固定i,j时产生的改变量,做$O(\sqrt{N})$次区间加(线段树或树状数组支持),每次取出G[i][j]的时候都额外查询一下[i][j]上的标记即可。

 

@Author: YouSiki

posted @ 2017-02-17 22:01  YouSiki  阅读(355)  评论(0编辑  收藏  举报