bzoj 2821 分块处理
大题思路就是分块,将n个数分成sqrt(n)个块,然后
处理出一个w数组,w[i,j]代表第i个块到第j个块的答案
那么对于每组询问l,r如果l,r在同一个块中,直接暴力做就行了
如果不在同一个块中,l,r区间中整块的部分可以直接由w数组得到答案
然后多出来的部分暴力处理下出现次数,然后再预处理一个b数组,代表没
个数出现的位置,且每个数都连续,那么我们可以二分的找出在多余部分出现的
每个数在整区间内出现多少次,然后和多余部分出现的累加,判断奇偶更新答案
看了lyd的题解,写的挺好(其实这个题就是他出的。。),然后我写的
pascal,他的C++的代码30s+A了,我就TLE了。。。
话说今儿LYD生日,然后SHY发了个说说祝他生日快乐,是我想多了。。。
/**************************************************************
Problem:
User: BLADEVIL
Language: Pascal
Result: Time_Limit_Exceed
****************************************************************/
//By BLADEVIL
{$inline on}
var
n, t, m :longint;
a, b, c :array[..] of longint;
st, ed, s, e, v, q :array[..] of longint;
w :array[..,..] of longint;
procedure swap(var a,b:longint);inline;
var
c :longint;
begin
c:=a; a:=b; b:=c;
end;
function calc(k,x,y:longint):longint;inline;
var
l, r, mid :longint;
begin
if x>y then exit();
l:=st[k]; r:=ed[k];
while l<r do
begin
mid:=(l+r+)>>;
if b[mid]<x then l:=mid else r:=mid-;
end;
if b[l]>=x then dec(l);
x:=l;
l:=st[k]; r:=ed[k];
while l<r do
begin
mid:=(l+r+)>>;
if b[mid]>y then r:=mid- else l:=mid;//
end;
if b[l]>y then dec(l);
y:=l;
exit(y-x);
end;
procedure main;inline;
var
i, j, k :longint;
p, tot, l, r :longint;
now, cnt :longint;
x, y :longint;
begin
read(n,t,m);
for i:= to n do read(a[i]);
for i:= to n do inc(c[a[i]]);
tot:=;
for i:= to t do
begin
st[i]:=tot+;
inc(tot,c[i]);
ed[i]:=tot;
end;
fillchar(c,sizeof(c),);
for i:= to n do
begin
b[st[a[i]]+c[a[i]]]:=i;
inc(c[a[i]]);
end;
p:=trunc(sqrt(n));
l:=n div p;
for i:= to p do
begin
s[i]:=(i-)*l+;
e[i]:=i*l;
end;
if e[p]<n then
begin
inc(p);
s[p]:=e[p-]+;
e[p]:=n;
end;
for i:= to p do
begin
fillchar(c,sizeof(c),);
now:=;
for j:=i to p do
begin
for k:=s[j] to e[j] do
begin
inc(c[a[k]]);
if (c[a[k]]>) and (c[a[k]] and <>)
then dec(now) else
if (c[a[k]] and )= then inc(now);
end;
w[i,j]:=now;
end;
end;
now:=;
for i:= to m do
begin
read(x,y);
x:=(x+now) mod n+;
y:=(y+now) mod n+;
if x>y then swap(x,y);
for j:= to p do
if x<=e[j] then
begin
l:=j;
break;
end;
for j:=p downto do
if y>=s[j] then
begin
r:=j;
break;
end;
now:=w[l+,r-];
if l=r then
begin
for j:=x to y do
if v[a[j]]<>i then
begin
v[a[j]]:=i;
c[a[j]]:=;
end else
begin
inc(c[a[j]]);
if (c[a[j]] and )<> then
dec(now) else inc(now);
end;
end else
begin
cnt:=;
for j:=x to e[l] do
if v[a[j]]<>i then
begin
v[a[j]]:=i;
c[a[j]]:=;
inc(cnt);
q[cnt]:=a[j];
end else inc(c[a[j]]);
for j:=s[r] to y do
if v[a[j]]<>i then
begin
v[a[j]]:=i;
c[a[j]]:=;
inc(cnt);
q[cnt]:=a[j];
end else inc(c[a[j]]);
for j:= to cnt do
begin
k:=calc(q[j],s[l+],e[r-]);
if k= then
begin
if c[q[j]] and = then inc(now)
end else
if (k and <>) and (c[q[j]] and <>) then inc(now) else
if (k and =) and (c[q[j]] and <>) then dec(now);
end;
end;
writeln(now);
end;
end;
begin
main;
end.
bzoj 2821 分块处理的更多相关文章
- bzoj 2821 分块
分块: 先预处理,将原序列分成长度为len的许多块,计算从第i块到第j块的答案,(可以做到O(n*n/len)). 每次询问时,将询问的区间分成三部分,:左边,中间,右边,中间是尽量大的一个块区间,其 ...
- BZOJ 2821 分块+二分
题意: N个数,M组询问,每次问[l,r]中有多少个数出现正偶数次. 思路: 把N个数分成sqrt(n)块,预处理d[i][j]表示第i块起点到第j块末尾的答案 枚举起点i,并维护一个数组记录每个数到 ...
- [BZOJ 2821] 作诗(Poetize) 【分块】
题目链接:BZOJ - 2821 题目分析 因为强制在线了,所以无法用莫队..可以使用分块来做. 做法是,将 n 个数分成 n/x 个块,每个块大小为 x .先预处理出 f[i][j] ,表示从第 i ...
- [BZOJ 2821] 作诗
Link: BZOJ 2821 传送门 Solution: 一道类似区间众数的经典分块 由于个数为偶数这样的条件不能支持快速合并 因此要先$O(n*sqrt(n))$预处理出$pre[i][j]$表示 ...
- BZOJ 2821: 作诗(Poetize)( 分块 )
分块,分成N^0.5块.O(N^1.5)预处理出sm[i][j]表示前i块中j的出现次数, ans[i][j]表示第i~j块的答案. 然后就可以O(N^0.5)回答询问了.总复杂度O((N+Q)N^0 ...
- BZOJ 2821作诗(Poetize) 分块
Description 有一个长度为n的序列,序列每个元素的范围[1,c],有m个询问x y,表示区间[x,y]中出现正偶数次的数的种类数. Solution 大力分块解决问题. 把序列分块,f[i] ...
- bzoj 2821 作诗 分块
基本思路和蒲公英一样 还是预处理出每两个块间的答案 询问时暴力跑两边的贡献 #include<cstdio> #include<cstring> #include<ios ...
- 【BZOJ 2821】作诗
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2821 [算法] 如果不强制在线,显然莫队是可以解决此题的,那么,强制在线怎么办呢? ...
- bzoj 2741 分块+可持久化trie
多个询问l,r,求所有子区间异或和中最大是多少 强制在线 做法: 分块+可持久化trie 1.对于每块的左端点i,预处理出i到任意一个j,()i,j)间所有子区间异或和中最大为多少,复杂度O(\(n\ ...
随机推荐
- C#关于值类型和引用类型的备忘
值类型 引用类型 内存分配地点 分配在栈中 分配在堆中 效率 效率高,不需要地址转换 效率低,需要进行地址转换 内存回收 使用完后,立即回收 使用完后,不是立即回收,等待GC回收 赋值操作 进行复 ...
- ES2015 ——let命令的暂时性死区
ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. 和var不同的还有,let命令不存在变量提升,所以声明前调用变量,都会报错,这就涉及到 ...
- PHP变量名区分大小写,函数名不区分大小写
PHP变量名区分大小写,函数名不区分大小写,经常被新手忽视的小细节,测试如下. PHP变量名区分大小写测试: <?php $aaa = "phpddt.com"; $AAA ...
- Hao123这个流氓
Author:KillerLegend Date:2014.2.27 From:http://www.cnblogs.com/killerlegend/p/3572591.html Hao123真让人 ...
- 给Activity设置背景颜色
为了使得错误提示更加显眼,再用Toast+振动效果之外考虑变换整个activity的背景颜色. 尝试一: activity并没像winform一样直接给个属性来设置,就想获取整个activity的la ...
- mysql数据库开发规范
对规范的遵守可用二八原则,不要教条.为满足实际需求 可忽视部分规范. 1.索引规范 *目标 |--利用最小的索引成本找到需要的行记录 *原则 |--做前缀匹配 |--选择区分度高的列做前缀索引列 |- ...
- 1.html5究竟是什么
1.html5的起源,历史背景…… 按照一般的套路,我这里应该对html5的起源和发展历史,其优越性等大书特书一番.但既然你有意识地专门去找类似的文章,说明你早有相应的认识,就算没有,类似的东西网上也 ...
- JS把函数当作参数传递
getDescPage("commonPage","/page/common/tips/tips.html",init()); $("#"+ ...
- hdu 5199 Gunner
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=5199 简单题,stl水之... #include<algorithm> #include& ...
- Windows Phone性能优化建议
使用background thread解码图片 在Windows Phone中支持的图片格式有jpg和png,微软建议使用jpg格式的图片,因为jpg格式的图片在解码速度上要比png快.那么我们怎么来 ...