题目分析:

首先这种乱七八糟的题目就分块。然后考虑逆序对的统计。

一是块内的,二是块之间的,三是一个块内一个块外,四是都在块外。

令分块大小为$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)$

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3
  4 const int srt = 250;
  5 const int maxn = 50100;
  6
  7 int n,m;
  8 int c[srt+5][maxn],inside[maxn],con[srt+5][srt+5];
  9 int a[maxn],ord[maxn];
 10
 11 int lowbit(int x){return x&-x;}
 12
 13 void add(int now,int dr,int om){while(now <= n)c[om][now]+=dr,now+=lowbit(now);}
 14 int query(int now,int om){
 15     int ans = 0;
 16     while(now){ans += c[om][now]; now -= lowbit(now);}
 17     return ans;
 18 }
 19 void Add(int now,int dr,int om){while(now<=n/srt+1){con[om][now]+=dr;now += lowbit(now);}}
 20 int Query(int now,int om){
 21     int ans = 0;
 22     while(now){ans += con[om][now]; now -= lowbit(now);}
 23     return ans;
 24 }
 25
 26 void read(){
 27     scanf("%d",&n);
 28     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
 29     scanf("%d",&m);
 30 }
 31
 32 void init(){
 33     for(int i=1,cnt=1;i<=n;i+=srt,cnt++){
 34     memset(c[0],0,sizeof(c[0]));
 35     for(int j=srt-1;j>=0;j--){
 36         if(j+i > n) continue;
 37         inside[cnt] += query(a[i+j]-1,0);
 38         add(a[i+j],1,0);
 39     }
 40     }
 41     for(int i=1;(i-1)*srt+1<=n;i++){
 42     memset(c[0],0,sizeof(c[0]));
 43     for(int j=(i-1)*srt+1;j<=min(n,i*srt);j++) add(a[j],1,0);
 44     for(int j=i+1;(j-1)*srt+1<=n;j++){
 45         for(int k=(j-1)*srt+1;k<=min(n,j*srt);k++)
 46         con[i][j] += query(n,0)-query(a[k],0);
 47     }
 48     }
 49     for(int i=1;(i-1)*srt+1<=n;i++){
 50     int j; for(j=i+1;(j-1)*srt+1<=n;j++);
 51     for(;j>i;j--){ int z = con[i][j]; con[i][j] = 0; Add(j,z,i); }
 52     for(int j=(i-1)*srt+1;j<=min(n,i*srt);j++){
 53         for(int k=i;(k-1)*srt+1<=n;k++) add(a[j],1,k);
 54     }
 55     }
 56 }
 57
 58 void work(){
 59     int lastans = 0;memset(c[0],0,sizeof(c[0]));
 60     for(int i=1;i<=m;i++){
 61     int pv; scanf("%d",&pv);
 62     if(pv == 0){
 63         int l,r; scanf("%d%d",&l,&r); l^=lastans; r^=lastans;
 64         if(r-l < srt){
 65         int ans = 0;
 66         for(int j=r;j>=l;j--){ans += query(a[j]-1,0);add(a[j],1,0);}
 67         for(int j=r;j>=l;j--){add(a[j],-1,0);}
 68         printf("%d\n",ans);lastans = ans;
 69         continue;
 70         }
 71         int st=1,ed=1;
 72         while((st-1)*srt+1 < l)st++; while(ed*srt<=r)ed++;ed--;
 73         int ans = 0; for(int j=st;j<=ed;j++)ans += inside[j];
 74         for(int j=st;j<=ed;j++){ans += Query(ed,j);}
 75         for(int j=l;j%srt!=1;j++)ans+=query(a[j]-1,ed)-query(a[j]-1,st-1);
 76         for(int j=ed*srt+1;j<=r;j++){
 77         ans += (query(n,ed)-query(n,st-1));
 78         ans -= (query(a[j],ed)-query(a[j],st-1));
 79         }
 80         for(int j=r;j>ed*srt;j--){ans += query(a[j]-1,0); add(a[j],1,0);}
 81         for(int j=(st-1)*srt;j>=l;j--){ans+=query(a[j]-1,0);add(a[j],1,0);}
 82         for(int j=r;j>ed*srt;j--) add(a[j],-1,0);
 83         for(int j=(st-1)*srt;j>=l;j--) add(a[j],-1,0);
 84         printf("%d\n",ans);lastans = ans;
 85     }else{
 86         int p,v; scanf("%d%d",&p,&v);p^=lastans,v ^= lastans;
 87         int bel = p/srt+(p%srt!=0);
 88         for(int j=(bel-1)*srt+1;j<p;j++){
 89         if(a[j] > a[p]) inside[bel]--; if(a[j] > v) inside[bel]++;
 90         }
 91         for(int j=p+1;j<=bel*srt;j++){
 92         if(a[j] < a[p]) inside[bel]--; if(a[j] < v) inside[bel]++;
 93         }
 94         for(int j=1;j<bel;j++){
 95         int z = (srt-query(a[p],j)+query(a[p],j-1));
 96         int zz = (srt-query(v,j)+query(v,j-1));
 97         Add(bel,zz-z,j);
 98         }
 99         for(int j=bel+1;(j-1)*srt+1<=n;j++){
100         int z=query(a[p]-1,j)-query(a[p]-1,j-1);
101         int r=query(v-1,j)-query(v-1,j-1);
102         Add(j,r-z,bel);
103         }
104         for(int j=bel;(j-1)*srt+1<=n;j++){add(a[p],-1,j); add(v,1,j);}
105         a[p] = v;
106     }
107     }
108 }
109
110 int main(){
111     read();
112     init();
113     work();
114     return 0;
115 }

转载于:https://www.cnblogs.com/Menhera/p/9558254.html

BZOJ3787 gty的文艺妹子序列 【树状数组】【分块】相关推荐

  1. bzoj4553 [Tjoi2016Heoi2016]序列 树状数组(区间最大值)+cqd

    [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 1006  Solved: 464 [Submit ...

  2. 牛客23054 华华开始学信息学 树状数组分块

    题目链接:牛客23054 华华开始学信息学 题目描述 因为上次在月月面前丢人了,所以华华决定开始学信息学.十分钟后,他就开始学树状数组了.这是一道树状数组的入门题: 给定一个长度为N的序列A,所有元素 ...

  3. POJ3468-A Simple Problem with Integers【线段树,树状数组,分块】

    正题 题目链接:我是链接 其实洛谷线段树模板也是一样的:三种方法AC评测链接 题目大意 要求支持区间修改,区间求和. 线段树 直接用一个lazy标记,在之前的博客里有说 code1 #include& ...

  4. LibreOJ 6277,6278,6280 数列分块入门1,2,4 树状数组,分块,线段树等.

    分块1 分块2 分块4 模板一共有九个.我试着在三天内做了3个. 应该不用超链接吧. 分块1 区间加,单点询问. 这不是裸的改版树状数组吗?用树状数组处理前缀和水过. #include<bits ...

  5. LibreOJ 6282,6284,6285 数列分块入门6,8,9 树状数组,分块,线段树等.

    分块6 分块8 分块9 终于结尾了. 诶?我定义的常量变成yuzu了?我不要可怜了? 可怜有剧毒!我再用可怜我要爆零了. 好吧其实是因为我研究了橘学.这里我推荐一下Citrus. 分块6 支持插入一个 ...

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

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

  7. P4093-[HEOI2016/TJOI2016]序列【CDQ分治,树状数组】

    正题 题目链接:https://www.luogu.com.cn/problem/P4093 题目大意 nnn个数字,每次有一个数字可能和原序列不同,但最多只有一个不同. 求所有情况下都满足的最长不降 ...

  8. BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j)if(a[j ...

  9. Vijos P1448 校门外的树【多解,线段树,树状数组,括号序列法+暴力优化】

    校门外的树 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的-- 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,K= ...

  10. 求序列最长不下降子序列_树状数组解决最长不下降子序列 讲讲主要思路就好...

    展开全部 不降子序列求的是一个元素的值单调e69da5e887aa62616964757a686964616f31333361306430不降的序列. 传统的状态设计便是使用f[n] 表示到达第n位时 ...

最新文章

  1. 近期活动盘点:首届Apache Flink 极客挑战赛、2019年社会计算机国际会议
  2. 数据泄漏保护:你的企业的投资是否足够?
  3. jquer 的简输出
  4. php array_merge 与 + 区别
  5. 20 WBS要素xxxxxx有不同的存货估价
  6. MapReduce中的排序(附代码)
  7. 统计数据:Google排名高的是什么样的页面?
  8. [转载] Python基础:什么是字符串?字符串是用来做什么的?
  9. TP收集一些可以用的资源
  10. php对浮点数小数取整,php除法取整数
  11. leetcode 859. Buddy Strings
  12. CTF知识总结--MISC
  13. vue实现div高度可拖拽
  14. css3制作翘边阴影
  15. WXGA TFT和XGA TFT的区别
  16. Opencv4.5.1 微信二维码识别功能 QRCode 编译与使用 C++
  17. R 和 Rstudio 在线更新
  18. BGA锡球选择与PITCH的关系
  19. OpenCv-C++-SURF特征检测
  20. QRCode生成二维码和解析二维码

热门文章

  1. pentaho mysql_pentaho bi server 配置MySQL数据库
  2. 从来没有一种工作叫钱多、事少、离家近
  3. html中怎么隐藏一些符号,html 的一些特殊符号
  4. C语言每日一练——第61天:掷骰子游戏
  5. 建无根树+无根树转有根树
  6. python单位根检验平稳性怎么看是否平稳_Python ADF单位根检验查看结果实现方法...
  7. 文件服务器如何设置配额,文件服务器设置配额
  8. matlab | 图像处理工具箱
  9. oracle isnull使用索引,isnull()用法总结
  10. 第三章:使用HiTool下载程序