bzoj3744
这道题是目前我做bzoj最感动的一题没有之一……
首先先警示一下,分块的题目能不套主席树尽量不套
因为主席树不仅回答来一个log而且常数也比较大,对于分块这种根号的算法非常不适合
这里是求区间逆序对,考虑查询,不难想到答案是[l,r]所夹整块之间的逆序对数目和两边的数所带来的逆序对数目和
首先第一部分是可以预处理出来的,算法是O(n*tot*logn)
第二部分裸的想法是求每个数ai在区间[l,i]比它小的个数,然后可以用主席树搞搞
但是不幸的是,这样直接T到死,自测bzoj第一点的数据就跑了24s……伤不起
所以考虑bzoj2724的做法,我们还是先预处理f[i,j],g[i,j]表示1~i块内比j大的数和比j小的数的个数
考虑两边的数ai,令它构成一个序列bj,这些数所带来的逆序对数目就是
如果ai在整块左边,就是=[l,r]所夹整块内比它小的数个数,在整块右边就是=[l,r]所夹整块内比它大的数个数
最后再加上bj序列的逆序对数目就是答案
考虑一种快速计算逆序对的算法,不难想到用树状数组,这已经相当优
下面就是令人感动的事情了,用树状数组替代主席树之后,程序已经能跑到28s左右
想办法干掉fillchar并在调整一下块的大小,优化到了23,24s左右
然后始终没能跑进20s……然后我就各种想,突然发现
当l正好是一个块的左端点时,我的程序仍然遍历了l所在的块(很多分块的程序都是这样),其实可以没必要
加了这个优化本地正好跑了20s,激动了,然后试着把r正好是块的右端点也特判一下
王苍啊,终于过了,在bzoj上跑了18s……
出题人大概是故意卡常数的吧……
有幸成为这道题第一个pascal通过者,非常感动(苦逼的pascal伤不起啊)
附上丑陋的代码:
const maxn=; var s:array[..,..] of longint;
f,g:array[..,..maxn] of longint;
co,v,a,be,b,c,rank,h:array[..maxn] of longint;
time,i,size,n,m,j,k,ans,x,y,t,tot,p:longint; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure add(x:longint);
begin
while x<=p do
begin
if v[x]<>time then
begin
c[x]:=;
v[x]:=time;
end;
inc(c[x]);
x:=x+lowbit(x);
end;
end; function ask(x:longint):longint;
begin
ask:=;
while x> do
begin
if v[x]<>time then //为了不用fillchar加了一个时间戳
begin
c[x]:=;
v[x]:=time;
end;
ask:=ask+c[x];
x:=x-lowbit(x);
end;
end; procedure sort(l,r: longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=b[(l+r) shr ];
repeat
while b[i]<x do inc(i);
while x<b[j] do dec(j);
if not(i>j) then
begin
swap(b[i],b[j]);
swap(h[i],h[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; function getans(l,r:longint):longint;
var i,j,x:longint;
begin
getans:=;
t:=;
if be[r]=be[l] then
begin
for i:=l to r do
begin
getans:=getans+t-ask(rank[i]);
add(rank[i]);
inc(t);
end;
end
else begin
x:=min(be[r]*size,n);
if ((be[l]-)*size+=l) and (x=r) then exit(s[be[l],be[r]]) //正好是端点可以直接计算
else if ((be[l]-)*size+=l) then
begin
getans:=getans+s[be[l],be[r]-];
for i:=(be[r]-)*size+ to r do
begin
x:=rank[i];
getans:=getans+f[be[r]-,x]-f[be[l]-,x];
getans:=getans+t-ask(x);
add(x);
inc(t);
end;
exit;
end
else if (x=r) then
begin
getans:=getans+s[be[l]+,be[r]];
for i:=l to be[l]*size do
begin
x:=rank[i];
getans:=getans+g[be[r],x]-g[be[l],x];
getans:=getans+t-ask(x);
add(x);
inc(t);
end;
exit;
end;
getans:=getans+s[be[l]+,be[r]-];
for i:=l to be[l]*size do
begin
x:=rank[i];
getans:=getans+g[be[r]-,x]-g[be[l],x];
getans:=getans+t-ask(x); //为了只调用一次查询
add(x);
inc(t);
end;
for i:=(be[r]-)*size+ to r do
begin
x:=rank[i];
getans:=getans+f[be[r]-,x]-f[be[l],x];
getans:=getans+t-ask(x);
add(x);
inc(t);
end;
end;
end; begin
readln(n);
size:=trunc(sqrt(n)/1.1);
for i:= to n do
begin
read(a[i]);
b[i]:=a[i];
h[i]:=i;
be[i]:=(i-) div size+;
end;
tot:=i div size;
if i mod size<> then inc(tot);
sort(,n);
p:=;
rank[h[]]:=;
for i:= to n do
begin
if b[i]<>b[i-] then inc(p);
rank[h[i]]:=p;
end;
for i:= to tot do //预处理f[i,j],g[i,j]
begin
x:=min(i*size,n);
for j:=(i-)*size+ to x do
inc(co[rank[j]]);
f[i,p]:=;
for j:=p- downto do
f[i,j]:=f[i,j+]+co[j+];
g[i,]:=;
for j:= to p do
g[i,j]:=g[i,j-]+co[j-];
end;
for i:= to tot do //预处理i~j块内的逆序对数
begin
t:=;
inc(time);
for j:=(i-)*size+ to n do
begin
x:=t-ask(rank[j]);
inc(s[i,be[j]],x);
add(rank[j]);
inc(t);
end;
for j:=i+ to tot do
s[i,j]:=s[i,j]+s[i,j-];
end;
ans:=;
readln(m);
for i:= to m do
begin
inc(time);
readln(x,y);
x:=x xor ans;
y:=y xor ans;
if x>y then swap(x,y);
ans:=getans(x,y);
writeln(ans);
end;
end.
bzoj3744的更多相关文章
- 【BZOJ3744】Gty的妹子序列 分块+树状数组
[BZOJ3744]Gty的妹子序列 Description 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzo ...
- bzoj3744 Gty的妹子序列
我是萌萌的传送门 感觉这题还是不错的--虽然其实算是比较水的题= = 首先分块,令f[i][j]表示第i块到第j块的逆序对数,询问的时候直接计算不完整块与完整块以及不完整块之间的逆序对. 不完整块之间 ...
- 【bzoj3744】GTY的妹子序列
大力分块+树状数组+主席树…… #include<bits/stdc++.h> #define N 50005 #define pa pair<int,int> #define ...
- 【分块】【树状数组】bzoj3744 Gty的妹子序列
离散化,分块. 预处理出:ans[i][j] 第i块到第j块的逆序对数. f[i][j] 第1~i块中大于j的数的个数. g[i][j] 第1~j块中小于j的数的个数. 每次询问时对于整块部分可以O( ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- BZOJ3744 Gty的妹子序列(分块+树状数组)
题意 询问区间内逆序对数 强制在线 1<=n<=50000 1<=m<=50000 题解 两个预处理f[i][j]为块i到j的逆序对数,s[i][j]前i块≤j的有多少个边角 ...
- bzoj3744: Gty的妹子序列 (BIT && 分块)
强制在线的区间询问逆序对数 如果不是强制在线 就是可以用莫队乱搞啦 强制在线的话 用f[i][j]记录第i块到第j个点之间的逆序对数 用s[i][j]记录前i块中小于等于j的数字个数 离散化一下 BI ...
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
- BZOJ_3744_Gty的妹子序列
BZOJ3744: Gty的妹子序列 https://lydsy.com/JudgeOnline/problem.php?id=3744 分析: 预处理出来每一块块首到所有位置的逆序对数. 查询时主席 ...
随机推荐
- 后端接收不到AngularJs中$http.post发送的数据的问题
1.问题: 后端接收不到AngularJs中$http.post发送的数据,总是显示为null 示例代码: $http.post(/admin/KeyValue/GetListByPage, { pa ...
- 十个最好的Java性能故障排除工具
1.jconsole 是随着JDK 1.5而推出的.这是一个Java监测和管理控制台-JMX兼容的图形工具来监测Java虚拟机.它能够同时监测本地和远程的JVMs.详情可查看:jconsole工具介 ...
- CentOS 6.7增加SWAP交换分区
任务:新增一个1GB的SWAP分区,并开机自动挂载 1.在/var目录下新增SWAPFILE交换区文件 2.生成SWAP分区 mkswap /var/SWAPFILE 3.激活SWAP分区 swapo ...
- Linux squid 安装配置
linux 代理软件 squid 查看是否安装squid 以上信息表明,本机是已经安装了此软件了 如果没有显示说明没有安装,则可以使用yum工具来安装 安装完软件后我们接着开始配置squid代 ...
- 编程基础-msdn编程指南笔记
此博仅为笔记,摘自msdn编程指南文档,链接地址:http://msdn.microsoft.com/zh-cn/library/67ef8sbd.aspx 注释:// 单行注释 /* 多行注释*/ ...
- 解决c#处理excel时故障 找不到可安装的 isam
直接拷贝的以前代码,但因软件版本,系统环境的变化,导致提示“找不到可安装的 isam”. 我目前新的软件环境:win8.1+office2010+vs2013 解决办法是修改连接字符串: 处理exce ...
- Composite 模式的实现
实现要点: 1.组合模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器. 2 ...
- POJ 3468.A Simple Problem with Integers 解题报告
用树状数组和线段树会比较简单,这里用这道题来学习Splay. 第一次写,代码比较丑 /* 初始化添加一个key值足够大的结点 保证每个需要的结点都有后继 */ #include <iostrea ...
- css3基础教程十六变形与动画animation
前面我们讲过的变形与动画一般都是通过鼠标的单击.获得焦点,被点击或对元素进行一定改变后以后触发效果的,那么有没有像Flash一样自动播放的动画效果呢?答案当然是肯定的,这就是我们今天要讲到的anima ...
- C#/.NET整数的三种强制类型转换(int)、Convert.ToInt32()、int.Parse()的区别
这三种方式都是强制把内容转换为整数,但他们之间是有区别的,如下: 一.(int)适合简单数据类型之间的转换,C#的默认整型是int32(不支持bool型). 二.int.Parse(string sP ...