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),因为预处理是用主席树查询的所以比较慢..块要开大一些
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 50500
#define M1 120
#define ll long long
#define uint unsigned int
using namespace std; template <typename _T> void read(_T &ret)
{
ret=; _T fh=; char c=getchar();
while(c<''||c>''){ if(c=='-') fh=-; c=getchar(); }
while(c>=''&&c<=''){ ret=ret*+c-''; c=getchar(); }
ret=ret*fh;
} struct SEG{
int ls[N1*],rs[N1*],sz[N1*],root[N1],tot;
void pushup(int rt){ sz[rt]=sz[ls[rt]]+sz[rs[rt]]; }
void upd(int x,int l,int r,int rt1,int &rt2,int w)
{
if(!rt2||rt1==rt2){ rt2=++tot; ls[rt2]=ls[rt1]; rs[rt2]=rs[rt1]; sz[rt2]=sz[rt1]; }
if(l==r){ sz[rt2]+=w; return; }
int mid=(l+r)>>;
if(x<=mid) upd(x,l,mid,ls[rt1],ls[rt2],w);
else upd(x,mid+,r,rs[rt1],rs[rt2],w);
pushup(rt2);
}
int query(int L,int R,int l,int r,int rt1,int rt2)
{
if(L<=l&&r<=R) return sz[rt2]-sz[rt1];
int mid=(l+r)>>,ans=;
if(L<=mid) ans+=query(L,R,l,mid,ls[rt1],ls[rt2]);
if(R>mid) ans+=query(L,R,mid+,r,rs[rt1],rs[rt2]);
return ans;
}
}s; int n,m,sq,Q,de; struct BIT{
int sum[N1];
int upd(int x,int w)
{
int i;
for(i=x;i<=m;i+=(i&(-i)))
sum[i]+=w;
}
int query(int x)
{
if(!x) return ; int i,ans=;
for(i=x;i>;i-=(i&(-i)))
ans+=sum[i];
return ans;
}
}bit; int a[N1],b[N1],pie[N1],st[M1],ed[M1];
uint f[N1][M1],g[M1][M1]; int main()
{
int i,j,k,l,r,q,x,y,px,py; uint ans=;
scanf("%d",&n);
for(i=;i<=n;i++) read(a[i]), b[i]=a[i];
sort(b+,b+n+); m=unique(b+,b+n+)-(b+);
for(i=;i<=n;i++) a[i]=lower_bound(b+,b+m+,a[i])-b;
for(i=;i<=n;i++) s.upd(a[i],,m,s.root[i-],s.root[i],); sq=;
for(i=;i<=n;i++) pie[i]=(i-)/sq+, ed[pie[i]]=i;
for(i=;i<=pie[n];i++) st[i]=(i-)*sq+;
for(i=;i<=n;i++)
{
if(a[i]<m)
{
for(j=;j<pie[i];j++)
f[i][j]=s.query(a[i]+,m,,m,s.root[st[j]-],s.root[i-]);
f[i][]=s.query(a[i]+,m,,m,s.root[st[pie[i]]-],s.root[i-]);
}
if(a[i]>)
{
for(j=pie[i];j<=pie[n];j++)
{
f[i][j]=s.query(,a[i]-,,m,s.root[i],s.root[ed[j]]);
g[pie[i]][j]+=f[i][j];
}
}
}
for(j=;j<=pie[n];j++)
for(i=;i+j<=pie[n];i++)
g[i][i+j]+=g[i+][i+j]; scanf("%d",&Q);
for(q=;q<=Q;q++)
{
read(x); read(y); x^=ans; y^=ans; ans=; px=pie[x]; py=pie[y];
if(px!=py){
if(px+<=py-) ans=g[px+][py-];
for(i=x;i<=ed[px];i++) ans+=f[i][py-];
if(px+==py){
for(i=st[py];i<=y;i++) ans+=f[i][];
}else{
for(i=st[py];i<=y;i++) ans+=f[i][px+];
}
for(i=st[py];i<=y;i++) bit.upd(a[i],);
for(i=x;i<=ed[px];i++) if(a[i]>) ans+=bit.query(a[i]-);
for(i=st[py];i<=y;i++) bit.upd(a[i],-);
}else{
for(i=y;i>=x;i--)
{
if(a[i]>) ans+=bit.query(a[i]-);
bit.upd(a[i],);
}
for(i=x;i<=y;i++) bit.upd(a[i],-);
}
printf("%u\n",ans);
}
return ;
}
BZOJ 3744 Gty的妹子序列 (分块+树状数组+主席树)的更多相关文章
- BZOJ 3744 Gty的妹子序列 (分块 + BIT)
3744: Gty的妹子序列 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1931 Solved: 570[Submit][Status][Dis ...
- BZOJ 3744: Gty的妹子序列 [分块]
传送门 题意:询问区间内逆序对数 感觉这种题都成套路题了 两个预处理$f[i][j]$块i到j的逆序对数,$s[i][j]$前i块$\le j$的有多少个 f我直接处理成到元素j,方便一点 用个树状数 ...
- BZOJ 3744 Gty的妹子序列 分块+树状数组
具体分析见 搬来大佬博客 时间复杂度 O(nnlogn)O(n\sqrt nlogn)O(nnlogn) CODE #include <cmath> #include <cctyp ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- BZOJ 3744 Gty的妹子序列 做法集结
我只会O(nnlogn)O(n\sqrt nlogn)O(nnlogn)的 . . . . 这是分块+树状数组+主席树的做法O(nnlogn)O(n\sqrt nlogn)O(nnlogn) 搬来 ...
- P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]
题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...
- BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树
BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...
- zoj2112 树状数组+主席树 区间动第k大
Dynamic Rankings Time Limit: 10000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Subm ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
随机推荐
- 为什么要阅读——兼分享《首先,打破一切常规》[中译文]:世界顶级管理者的成功秘诀/(美)马库斯·白金汉,(美)柯特·科夫曼 著
<ctrlno=255632">首先,打破一切常规>[中译文]:世界顶级管理者的成功秘诀/(美)马库斯·白金汉,(美)柯特·科夫曼 著:鲍世修 等译 下载地址:http:/ ...
- OC3大回调模式使用总结(三)block回调
OC 3大回调模式使用总结(三)block回调 block 又称 代码块,闭包等 是一个匿名的函数,它能够当做一个对象来使用,仅仅只是这个对象非常特殊,是一段代码,他能够保存你写的一段预备性质代码,待 ...
- 蒟蒻的trie树专题
POJ 3630 Phone List: 模板 ///meek #include<bits/stdc++.h> using namespace std; using namespace s ...
- bzoj3110 [Zjoi2013]K大数查询——线段树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3110 外层权值线段树套内层区间线段树: 之所以外层权值内层区间,是因为区间线段树需要标记下传 ...
- KNN in c++
Pseudo Code of KNN We can implement a KNN model by following the below steps: Load the data Initiali ...
- Django day07 (一) 模板的导入 母板的继承 静态文件配置
一:模板的导入 -写一个模板 {% include '模板的名字' %} 二:母板的继承 -写一个母版(可以留多个盒子) {% block 名字 %} / {% endblock %} 三:静态文件配 ...
- Java多线程技术-Volatile关键字解析
分析volatile关键字可以从这三个方面分析,什么是程序的原子性,什么是程序的可见性,什么是程序的有序性 什么是程序的原子性 以下语句那些是原子操作? public class ThreadCoun ...
- Asp.net MVC访问框架页中嵌套的iframe页面时,如果session或cookie过期,登录验证超时怎样自动跳转到登录页
一般登录验证的过滤器中,使用验证过滤器的Redirect方法,将请求重定向到指定的URL.但是如果我们要访问的页面是一个嵌套在框架页中的iframe页面时,这种重定向只会对iframe页面凑效,也就是 ...
- jquery插件之倒计时-团购秒杀
1.1 帮助文档关键字 倒计时 秒杀 timer 1.2. 使用场景 这样的倒计时在购物网站中会经常使用到,比如秒杀,限时抢购,确认收货倒计时. 这个功能并不难实现,就是利用js的定时执行,搜了 ...
- Excel的用到的常规的技巧
这几天在做各种发票的报表,好几百的数据当然离不开EXCel,自己又是个白班,就记录下啦! EXCEL 判断某一单元格值是否包含在某一列中 就在Excel的表格中加入这个函数:=IF(ISERROR(V ...