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条高 ...
随机推荐
- android.os.Process.killProcess(android.os.Process.myPid())与Activity生命周期的影响
如果通过finish方法结束了一个Activity,那么根据Activity的生命周期,则会自动调用Activity的销毁方法onDestory(),但是在项目中遇到这样的一个问题,就是Activi ...
- Androlid入门之文件系统操作(三)文件读写
import java.io.*; import android.app.Activity; import android.os.Bundle; import android.view.Vi ...
- 1tb等于多少g 1TB和500G有什么区别
转自:http://www.a207.com/article/view_39392 移动硬盘.U盘是生活中常见的用品,他们的内存大小是什么标准.很多人对于1tb等于多少g和1tb和500g有什么区别不 ...
- Flink之DataStreamAPI入门
目录 Types Transformations Defining UDFs 本文API基于Flink 1.4 def main(args: Array[String]) { // 第一种会自动判断用 ...
- PCB MS SQL 排序应用---SQL相邻数据区间值求解
其中一篇 博文中有写<PCB MS SQL 排序应用---相邻数据且相同合并处理>此篇有也应相用也同的技巧,实现相邻数据区间值求解 示例: 原数据:处理前 求出区间值:处理后 SQL 代码 ...
- nodejs安装express
最近在看<Node.js开发指南>,看到使用nodejs进行web开发的时候,准备创建ejs项目遇到问题了, 书上命令为: 1 express -t ejs microblog 可是执行后 ...
- 原生JS---1
js的历史 在上个世纪的1995年,当时的网景公司正凭借其Navigator浏览器成为Web时代开启时最著名的第一代互联网公司. 由于网景公司希望能在静态HTML页面上添加一些动态效果,于是叫Bren ...
- [Apple开发者帐户帮助]六、配置应用服务(1.2)Apple Pay:在网络上配置Apple Pay
网上Apple Pay允许用户在您的网络应用中购买商品和服务. 首先在您的开发者帐户中创建一个商家标识符,该标识符可以将Apple Pay唯一标识为能够接受付款的商家.您可以为多个本机和Web应用程序 ...
- POJ 2976 裸的01分数规划
题意:给你n个数对(认为是a数组和b数组吧),从中取n-m个数对,如果选第i个数对,定义x[i]=1,求R=∑(a[i]*x[i])/∑(b[i]*x[i])取得最大值时R的值.输出R*100(保留到 ...
- Prism.Interactivity 之 PopupWindowAction 用法简记
PopupWindow通过InteractionRequestTrigger(EventTrigger的派生类)侦听目标对象(InteractionRequest<T>类型)的Raised ...