当前位置: 首页 > news >正文

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

题面传送门

题目大意:给你一个序列,多次询问,每次取出一段连续的子序列$[l,r]$,询问这段子序列的逆序对个数,强制在线

 

很熟悉的分块套路啊,和很多可持久化01Trie的题目类似,用分块预处理出贡献,而这道题是用可持久化线段树罢了

首先对序列分块,设块大小为$S$

再建出主席树,我们就能在$O(logn)$时间内查询某个点$i$与区间$[l,r]$内的点产生的逆序对数量

然后处理出点和整块之间的答案,设$f(i,j)$表示第$i$个点与第$j$块的开始/末尾这段区间内的点产生的逆序对数量。

再根据 点到块的答案 统计出 块到块的答案

对于每次询问,利用预处理出的东西$O(1)$搞出 整块到整块 的贡献,再暴力枚举边角+主席树查询搞出 边角到整块 和 边角到边角 的贡献。

然后就会被卡常

我们可以用树状数组搞出 边角到边角 的贡献,再用预处理的信息搞出 边角对整块 的贡献...

虽然每次查询的时间也是$O(logn)$不变,但非递归的树状数组确实能减少大量的常数 #喷血

分析一下时间复杂度,预处理+查询=O(n\frac{n}{S}logn+QSlogn),因为预处理是用主席树查询的所以比较慢..块要开大一些

 

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #define N1 50500
  6 #define M1 120
  7 #define ll long long 
  8 #define uint unsigned int 
  9 using namespace std;
 10 
 11 template <typename _T> void read(_T &ret)
 12 {
 13     ret=0; _T fh=1; char c=getchar();
 14     while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); }
 15     while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
 16     ret=ret*fh;
 17 }
 18 
 19 struct SEG{
 20 int ls[N1*20],rs[N1*20],sz[N1*20],root[N1],tot;
 21 void pushup(int rt){ sz[rt]=sz[ls[rt]]+sz[rs[rt]];  }
 22 void upd(int x,int l,int r,int rt1,int &rt2,int w)
 23 {
 24     if(!rt2||rt1==rt2){ rt2=++tot; ls[rt2]=ls[rt1]; rs[rt2]=rs[rt1]; sz[rt2]=sz[rt1]; }
 25     if(l==r){ sz[rt2]+=w; return; }
 26     int mid=(l+r)>>1;
 27     if(x<=mid) upd(x,l,mid,ls[rt1],ls[rt2],w);
 28     else upd(x,mid+1,r,rs[rt1],rs[rt2],w);
 29     pushup(rt2);
 30 }
 31 int query(int L,int R,int l,int r,int rt1,int rt2)
 32 {
 33     if(L<=l&&r<=R) return sz[rt2]-sz[rt1];
 34     int mid=(l+r)>>1,ans=0;
 35     if(L<=mid) ans+=query(L,R,l,mid,ls[rt1],ls[rt2]);
 36     if(R>mid) ans+=query(L,R,mid+1,r,rs[rt1],rs[rt2]);
 37     return ans;
 38 }
 39 }s;
 40 
 41 
 42 int n,m,sq,Q,de;
 43 
 44 struct BIT{
 45 int sum[N1];
 46 int upd(int x,int w)
 47 {
 48     int i;
 49     for(i=x;i<=m;i+=(i&(-i)))
 50         sum[i]+=w;
 51 }
 52 int query(int x)
 53 {
 54     if(!x) return 0; int i,ans=0; 
 55     for(i=x;i>0;i-=(i&(-i)))
 56         ans+=sum[i];
 57     return ans;
 58 }
 59 }bit;
 60 
 61 int a[N1],b[N1],pie[N1],st[M1],ed[M1];
 62 uint f[N1][M1],g[M1][M1];
 63 
 64 int main()
 65 {
 66     int i,j,k,l,r,q,x,y,px,py; uint ans=0;
 67     scanf("%d",&n);
 68     for(i=1;i<=n;i++) read(a[i]), b[i]=a[i];
 69     sort(b+1,b+n+1); m=unique(b+1,b+n+1)-(b+1);
 70     for(i=1;i<=n;i++) a[i]=lower_bound(b+1,b+m+1,a[i])-b;
 71     for(i=1;i<=n;i++) s.upd(a[i],1,m,s.root[i-1],s.root[i],1);
 72     
 73     sq=450;
 74     for(i=1;i<=n;i++) pie[i]=(i-1)/sq+1, ed[pie[i]]=i;
 75     for(i=1;i<=pie[n];i++) st[i]=(i-1)*sq+1;
 76     for(i=1;i<=n;i++)
 77     {
 78         if(a[i]<m)
 79         {
 80             for(j=1;j<pie[i];j++)
 81                 f[i][j]=s.query(a[i]+1,m,1,m,s.root[st[j]-1],s.root[i-1]);
 82             f[i][0]=s.query(a[i]+1,m,1,m,s.root[st[pie[i]]-1],s.root[i-1]);
 83         }
 84         if(a[i]>1)
 85         {
 86             for(j=pie[i];j<=pie[n];j++)
 87             {
 88                 f[i][j]=s.query(1,a[i]-1,1,m,s.root[i],s.root[ed[j]]);
 89                 g[pie[i]][j]+=f[i][j];
 90             }
 91         }
 92     }
 93     for(j=1;j<=pie[n];j++)
 94     for(i=1;i+j<=pie[n];i++)
 95         g[i][i+j]+=g[i+1][i+j];
 96     
 97     scanf("%d",&Q);
 98     for(q=1;q<=Q;q++)
 99     {
100         read(x); read(y); x^=ans; y^=ans; ans=0; px=pie[x]; py=pie[y];
101         if(px!=py){
102             if(px+1<=py-1) ans=g[px+1][py-1];
103             for(i=x;i<=ed[px];i++) ans+=f[i][py-1];
104             if(px+1==py){ 
105                 for(i=st[py];i<=y;i++) ans+=f[i][0];
106             }else{ 
107                 for(i=st[py];i<=y;i++) ans+=f[i][px+1]; 
108             }
109             for(i=st[py];i<=y;i++) bit.upd(a[i],1);
110             for(i=x;i<=ed[px];i++) if(a[i]>1) ans+=bit.query(a[i]-1); 
111             for(i=st[py];i<=y;i++) bit.upd(a[i],-1);
112         }else{
113             for(i=y;i>=x;i--) 
114             {
115                 if(a[i]>1) ans+=bit.query(a[i]-1);
116                 bit.upd(a[i],1);
117             }
118             for(i=x;i<=y;i++) bit.upd(a[i],-1);
119         }
120         printf("%u\n",ans);
121     }
122     return 0;
123 }

 

转载于:https://www.cnblogs.com/guapisolo/p/10603552.html

相关文章:

  • 前端——HTML
  • Kali Linux Metasploit Framework
  • 位运算的初了解(二)
  • AtCoder Beginner Contest 120 题解
  • 第三章小结
  • 微信小程序_(组件)icon、text、rich-text、progress四大基础组件
  • 处理机调度算法
  • 上周热点回顾(3.25-3.31)
  • 软工第三次团队作业 - 功能规格说明书
  • [北航软工]技术规格说明书
  • PAT甲级1068 Find More Coins【01背包】
  • 【BZOJ2125】—最短路(圆方树+树链剖分)
  • Java学习笔记-正则表达式
  • centos7.5搭建zabbix3.4.x以及mysql定制化监控
  • java ReentrantLock
  • [笔记] php常见简单功能及函数
  • 【Amaple教程】5. 插件
  • 03Go 类型总结
  • Android优雅地处理按钮重复点击
  • Apache Pulsar 2.1 重磅发布
  • mysql innodb 索引使用指南
  • MySQL QA
  • Netty 4.1 源代码学习:线程模型
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • Redis中的lru算法实现
  • windows-nginx-https-本地配置
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 微信开放平台全网发布【失败】的几点排查方法
  • Java总结 - String - 这篇请使劲喷我
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 数据库巡检项
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • # 达梦数据库知识点
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • $.ajax()
  • $.ajax,axios,fetch三种ajax请求的区别
  • (02)vite环境变量配置
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (二)c52学习之旅-简单了解单片机
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (过滤器)Filter和(监听器)listener
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (转)关于多人操作数据的处理策略
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (转)我也是一只IT小小鸟
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • @GetMapping和@RequestMapping的区别
  • [ IO.File ] FileSystemWatcher