博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 3787: Gty的文艺妹子序列
阅读量:4700 次
发布时间:2019-06-09

本文共 2149 字,大约阅读时间需要 7 分钟。

3787: Gty的文艺妹子序列

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

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

[ ][ ][ ]

 

又是分块,然后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

转载于:https://www.cnblogs.com/yousiki/p/6411675.html

你可能感兴趣的文章
找工作的一些感悟——前端小菜的成长
查看>>
C#委托和事件的应用Observer模式实例
查看>>
codevs1018 单词接龙(DFS)
查看>>
内容分发系统MediaEW:助新闻媒体转投HTML5
查看>>
HTML5 Canvas ( 径向渐变, 升级版的星空 ) fillStyle, createRadialGradient
查看>>
Stanford Local Programming Contest 2011
查看>>
多线程中,NSOperationQueue和GCD的区别
查看>>
python生成.exe文件
查看>>
PHP面向对象(OOP)----分页类
查看>>
监听SD卡状态
查看>>
vs2017 EFCore 迁移数据库命令
查看>>
serialVersionUID的作用
查看>>
liunx trac 插件使用之GanttCalendarPlugin
查看>>
(14)嵌入式软件开发工程师技能要求总结
查看>>
[hackerrank]Closest Number
查看>>
volatile关键字
查看>>
[Android] TabLayout设置下划线(Indicator)宽度
查看>>
<潭州教育>-Python学习笔记@条件与循环
查看>>
web自动化之验证码识别解决方案
查看>>
netty接收大文件的方法
查看>>