• 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(Nsqrt{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

  • 相关阅读:
    html框内文字垂直居中的方法
    关于 TensorFlow
    用windows自带的ftp.exe实现断点续传的方法
    Bat脚本处理ftp超强案例解说
    用winrar和ftp命令实现自动备份文件并自动上传到指定的ftp服务器
    在ubuntu上利用科大讯飞的SDK实现语音识别-语义识别等功能
    Linux音频编程--使用ALSA库播放wav文件
    使用iconv进行文件编码转换
    嵌入式Linux-LCD显示多行文字
    使用freetype来显示中文汉字和英文字符
  • 原文地址:https://www.cnblogs.com/yousiki/p/6411675.html
Copyright © 2020-2023  润新知