P2801 教主的魔法

区间加区间查询一个数排名。

对于每个块,维护其有序序列。修改时散块暴力重构,整块打tag。

查询是简单的。时间复杂度 \(O(n\log B+\dfrac{qn}{B}\log B+qB)\)。

\(B=\sqrt{n\log n}\)时复杂度为\(O(n\sqrt{n}\log n)\)。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int a[maxn],bel[maxn],n,q,B,cnt;
vector<int> e[5005];
int tag[5005],L[5005],R[5005];
void rebuild(int u){//
for(int i=L[u];i<=R[u];i++)a[u]+=tag[u];
e[u].clear();
for(int i=L[u];i<=R[u];i++)e[u].push_back(a[i]);
sort(e[u].begin(),e[u].end());
tag[u]=0;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>q;
B=1500;
for(int i=1;i<=n;i++){
cin>>a[i];
bel[i]=(i+B-1)/B;
e[bel[i]].push_back(a[i]);
}
cnt=(n+B-1)/B;
for(int i=1;i<=cnt;i++){
L[i]=R[i-1]+1;R[i]=L[i]+e[i].size()-1;
sort(e[i].begin(),e[i].end());
}
for(int i=1;i<=q;i++){
char tp;
int l,r,c;
cin>>tp>>l>>r>>c;
if(tp=='M'){
if(bel[l]==bel[r]){
for(int j=l;j<=r;j++)a[j]+=c;
rebuild(bel[l]);
}else{
for(int j=l;j<=R[bel[l]];j++)a[j]+=c;
rebuild(bel[l]);
for(int j=L[bel[r]];j<=r;j++)a[j]+=c;
rebuild(bel[r]);
for(int j=bel[l]+1;j<bel[r];j++)tag[j]+=c;
}
}else{
int res=0;
if(bel[l]==bel[r]){
for(int j=l;j<=r;j++){
if(a[j]+tag[bel[l]]>=c)res++;
}
}else{
for(int j=l;j<=R[bel[l]];j++){
if(a[j]+tag[bel[l]]>=c)res++;
}
for(int j=L[bel[r]];j<=r;j++){
if(a[j]+tag[bel[r]]>=c)res++;
}
for(int j=bel[l]+1;j<bel[r];j++){
int pos=lower_bound(e[j].begin(),e[j].end(),c-tag[j])-e[j].begin();
res+=(R[j]-L[j]+1)-pos;
}
}
cout<<res<<endl;
}
}
return 0;
}

P5356 [Ynoi2017] 由乃打扑克

区间加区间第k小。

修改同上题,查询将两散块归并起来,然后进行二分答案。

复杂度 \(O(B+\dfrac{n}{B}+q(B+\dfrac{n}{B}\log B\log V))\)。

取 \(B=\sqrt{n}\log n\),复杂度 \(O(n\sqrt{n}\log V)\)。

口胡完毕,代码没调。

P2496 体育课

区间加等差数列公差为正,区间最值。

修改在每个块上打两个标记:整体加和公差d。

修改时散块暴力重构,整块打标记。

每块维护最大值位置,显然这个单调递增。整块处理时check一下就可以了。

P3604 美好的每一天

HOI4战犯表示不理解一堆人跳楼带来的美感

询问小写字符串区间中有多少个子区间是可以被重排为回文串的。

重排为回文串的条件是至多有一种字母个数是奇数。

考虑状压字符出现次数,即是否为 \(0\) 或 \(2^k\)。

考虑前缀异或,一个串可以被表示为 \(s_r\ \text{xor}\ s_{l-1}\)。

于是加入一个字符的时候,贡献就可以由被这个字符位置上为 \(1\) 的这个数异或上 \(2^k\) 或 \(0\) 得到。

莫队,同时维护哈希表即可。

P5072 [Ynoi2015] 盼君勿忘

询问一个区间所有子序列的分别去重后的和 \(\bmod\) 给定的 \(p\)(不同)

如果一个数 \(x\) 在长度为 \(len\) 的区间出现了 \(cnt\) 的贡献:\(x2^{cnt}-x2^{len-cnt}\)。

第一个是容易的,而第二个可以把 \(cnt\) 相同的东西一起计算。

而不同的 \(cnt\) 只有 \(\sqrt{n}\) 种。可以使用哈希表维护。()

回滚莫队:

对于左端点在同一个块的东西:

先把右端点向右(这是单调的),左端点再向左,然后撤销回来。

不加莫队是等价的。

P8078 [WC2022] 秃子酋长

给一个长为 \(n\) 的排列 \(a_1,\dots, a_n\),有 \(m\) 次询问,每次询问区间 \([l, r]\) 内,排序后相邻的数在原序列中的位置的差的绝对值之和。

删除的话是容易使用链表维护的。于是就是不加莫队板子。

C765F Souvenirs

求出区间内差的绝对值的最小值。

考虑设 \(d(i,j,0)\) 为 \(i\) 所在块的 \(l_i\sim i\) 到第 \(i+1\sim j\) 块的贡献。

\(d(i,j,1)\) 则为 \(i\) 所在块的 \(i\sim r_i\) 到 \(j\sim i-1\) 块的答案。

显然我们可以先算出一个点到一个块,再前缀/后缀 \(\max\) 算出一段前缀/后缀到一个块,再前缀/后缀得到 \(d\) 数组。

对于一个点到一个块:

首先我们把每个串内部排序并记下来每个位置对应排序后哪个位置。(这里顺便解决了同一块的询问和散块贡献)

此部分复杂度 \(O(n\log B)\)。

在 \(i\) 块排序后数组枚举,可以双指针得到答案。此部分连同前缀后缀 \(\max\) 复杂度 \(O(n\sqrt n)\)。

这样处理了整散块贡献。

散块之间直接在排序之后的数组上归并起来即可。

对于整块到整块,考虑预处理 \(S(i,j)\) 为第 \(i\sim j\) 串答案。

首先容易处理块内答案。然后可以用 \(d\) 转移。此部分复杂度 \(O(n)\)。

综上,我们使用 \(O(n\sqrt n)\) 复杂度解决了问题。

值得一提的是,本题存在较多种解法,回滚莫队+链表、回滚莫队+bitset 以及另一种分块等均能解决该问题。

BZOJ4358 permu

给出一个长度为 \(n\) 的排列 P,以及 \(m\) 个询问。每次询问某个区间 \([l,r]\) 中,最长的值域连续段长度。

加入时用链表合并即可。

P5386 [Cnoi2019] 数字游戏

给定一个排列,多次询问,求一个区间 \([l,r]\) 有多少个子区间的值都在区间 \([x,y]\) 内。

就是求所有连续 \(01\) 的 \(\binom{len}{2}\)。

但是按秩合并并查集是 \(O(\log)\) 的,很不好。

考虑对 \(1\sim n\) 分块+链表维护,可以做到\(O(1)-O(\sqrt{n})\),正好契合莫队复杂度需求,还支持撤销。

P6578 [Ynoi2019] 魔法少女网站

不是你没有自杀就玩不了游戏是吗

单点带修,询问有区间多少子区间最大值 \(\le x\)。

对操作分块:对询问按 \(x\) 排序,顺次加入数,和上题一样的序列分块维护不修改的点。

对于每个询问,做一遍操作,然后再撤销操作即可。

\(O(n\sqrt{n})\)/

P3674 小清新人渣的本愿

询问区间是否能找到两个数和/差/积为给定数。

维护前缀bitset。和差就移位搞下就可以了。

然后积直接暴力分解。\(O(n(\sqrt{n}+\dfrac{n}{w}))\)。

P4688 [Ynoi2016] 掉进兔子洞

lxl还是身体力行一下跳楼吧!

询问三个区间,把三个区间中同时出现的数一个一个删掉,问最后三个区间剩下的数的个数和,询问独立。

考虑每个数的负贡献。就是三个区间的和减去重复出现的数的值\(\times 3\)。

改一下离散化方法,改成排排名的方法:1 2 2 3 3\(\to\)1 2 2 4 4

这个时候可以莫队搞。注意询问需要分下组,避免空间炸炸炸。

(早期暴戾代码)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=N/3+10;
int n,m,maxn;
int a[N],ans[M],cnt[N];
bitset<N> sum[M],cur;
struct Q
{
int l,r,k;
bool operator <(const Q &x)const
{
if(l/maxn!=x.l/maxn)return l<x.l;
return (l/maxn)&1?r<x.r:r>x.r;//奇偶排序
}
}q[M*3];
int t[N];
void lsh()
{
for(register int i=1;i<=n;++i)t[i]=a[i];
stable_sort(t+1,t+n+1);
for(register int i=1;i<=n;++i)a[i]=lower_bound(t+1,t+n+1,a[i])-t;
}
void add(int x)
{
cur.set(x+cnt[x]++);
}
void sub(int x)
{
cur.reset(x+--cnt[x]);
}
void solve()
{
int nowcnt=0,fuck;
cur.reset();
for(fuck=0;fuck<M-5&&m;++fuck)
{
--m;
ans[fuck]=0;
sum[fuck].set();
for(register int j=0;j<3;++j)
{
cin>>q[nowcnt].l>>q[nowcnt].r;
q[nowcnt].k=fuck;
ans[fuck]+=q[nowcnt].r-q[nowcnt].l+1;
++nowcnt;
}
}
stable_sort(q,q+nowcnt);
for(register int i=0,l=1,r=0;i<nowcnt;++i)
{
while(l>q[i].l)add(a[--l]);
while(r<q[i].r)add(a[++r]);
while(l<q[i].l)sub(a[l++]);
while(r>q[i].r)sub(a[r--]);
sum[q[i].k]&=cur;
}
for(register int i=0;i<fuck;++i)
{
cout<<ans[i]-(int)sum[i].count()*3<<endl;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
lsh();
maxn=n/sqrt(m);
solve();memset(cnt,0,sizeof(cnt));solve();memset(cnt,0,sizeof(cnt));solve();
return 0;
}

P5309 [Ynoi2011] 初始化

修改给定\(x,y(y<x)\),\(a_{y+kx}+=v\)。区间和。

根号分治。对于 \(x>\sqrt{n}\),\(O(1)-O(\sqrt{n})\)分块。

对于\(x\le \sqrt{n}\),记修改 \(x\) 的 \(y\) 的 \(v\) 的前缀后缀和。

注意到其实是对\(x\)为大小分了块,每块大小相同。散快前缀和即可。

P5397 [Ynoi2018] 天降之物

终于正常一点

序列 a,两种操作。

把所有 \(x\) 变成 \(y\)。查询最小的 \(|i − j|\) 使得 \(a_i = x, a_j = y\)。

根号分治,先考虑无修改的情况。

对于每个值维护其出现的位置集合。如果超过 \(B\) 就预处理出他到每个小点的答案。

如果小于 \(B\) 询问时就直接归并位置集合。

修改:

考虑对大点维护一个“没有被处理的小点集合”。

修改:小-小:直接合并;小-大 扔进没处理里面,到了\(B\)就重构;大大直接合并重构。

查询:归并未处理集合,查询已处理答案。复杂度竟然是对的。

Nityacke's 分块(未补全)的更多相关文章

  1. 记录一次bug解决过程:else未补全导致数据泄露和代码优化

    一.总结 快捷键ctrl + alt + 四个方向键 --> 倒置屏幕 未补全else逻辑,倒置查询数据泄露 空指针是最容易犯的错误,数据的空指针,可以普遍采用三目运算符来解决 SVN冲突解决关 ...

  2. Python Beautiful Soup学习之HTML标签补全功能

    Beautiful Soup是一个非常流行的Python模块.该模块可以解析网页,并提供定位内容的便捷接口. 使用下面两个命令安装: pip install beautifulsoup4 或者 sud ...

  3. VIM自动补全插件 - YouCompleteMe--"大神级vim补全插件"

    VIM自动补全插件 - YouCompleteMe 序言 vim 之所以被称为编辑器之神多半归功于其丰富的可DIY的灵活插件功能,( 例如vim下的这款神级般的代码补全插件YouCompleteMe) ...

  4. 我的Vim配置(自动补全/树形文件浏览)

    配置文件的下载路径在这里  http://files.cnblogs.com/files/oloroso/vim.configure.xz.gz 这实际上是一个 xz 格式的文件,添加的 gz 文件后 ...

  5. Vim自动补全神器:YouCompleteMe

    第一次听说这个插件还是在偶然的情况下看到别人的博客,听说了这个插件的大名.本来打算在实训期间来完成安装的,无奈网实在不给力,也就拖到了回家的时候.在开始准备工作的时候就了解到这个插件不是很容易安装,安 ...

  6. ubuntu1204上不能正常用emacs配合gocode进行自动补全

    我按gocode的页面https://github.com/nsf/gocode上去做,可是还是未成功,,我确认auto-complete在c-mode中是可以使用的,因为有补全出来了, 我再找了ht ...

  7. python tab补全

    一.python tab补全 前提:tab补全先检查readline包是否安装,未安装通过yum安装即可 [root@CentOS_11 day01]# rpm -qa |grep readliner ...

  8. Vim自动补全神器:YouCompleteMe(转)

    转自:http://blog.jobbole.com/58978/ 可能会有一段时间写linxu,免不了用vim,留着,找时间实操之 原文出处: marchtea 的博客 第一次听说这个插件还是在偶然 ...

  9. vim自动补全文章搜集

    引用文章A:http://blog.csdn.net/wendy260310/article/details/18035555 文章介绍:添加C++标准库的tags文件方法.(中文版) 引用文章B:h ...

  10. vim下使用YouCompleteMe实现代码提示、补全以及跳转设置

    配置YouCompleteMe 1. 安装vundle vundle是一个管理vim插件的工具,使用vundle安装YouCompleteMe比较方便. 按照作者在https://github.com ...

随机推荐

  1. Java基础总结大纲(一)

    1.JVM.JRE.和JDK的区别: JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性.说明:java是跨平台的而JVM不是跨平台的,正对的不同的语言 ...

  2. 利用 Java 实现组合式解析器

    Ward Cunningham 曾经说过,干净的代码清晰地表达了代码编写者所想要表达的东西,而优美的代码则更进一步,优美的代码看起来就像是专门为了要解决的问题而存在的.在本文中,我们将展示一个组合式解 ...

  3. idea springboot 微服务批量启动

    概要 在使用IDEA开发微服务的时候,微服务比较多,启动起来比较麻烦,下面介绍一下使用批量启动微服务的方法. 方法 编辑当前项目根目录下的 .idea\workspace.xml 文件. 找到 < ...

  4. HTML5 表单新的 Input 类型

    H5新增了电子邮箱,手机号码,网址,数量,搜索,范围,颜色选择,时间日期等input类型 1.电子邮箱 type="email" 提供电子邮箱格式验证 如果格式不对,会阻止表单提交 ...

  5. 构建你的.NET Aspire解决方案

    .NET Aspire 是一组功能强大的工具.模板和包,用于构建可观察的生产就绪应用程序..NET Aspire 通过处理特定云原生问题的 NuGet 包集合提供.云原生应用程序通常由小型互连部分或微 ...

  6. Qt+OPC开发笔记(一):OPCUA介绍、open62541介绍、编译与基础环境Demo

    前言   本篇介绍OPC协议,相关开源库.编译并搭建Qt开发OPC的基础环境.   Demo      OPC   OPC(OLE for Process Control)是一个工业标准,用于实现工业 ...

  7. 如何调整Gitlab-Runner最大并发数?

    概述: 我们在使用gitlab-runner做cicd时,如果安装之后没有配置gitlab-runner的最大并发数,在使用时候可能会碰到job的警告(job日志超过字节限制):job's log e ...

  8. 问题解决:curl: (7) Failed to connect to raw.githubusercontent.com port 443: 拒绝连接

    Ubuntu20.04下,安装Ros 指令curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key 报错:cur ...

  9. 转载 OKHttp使用详解

      一,OKHttp介绍 okhttp是一个第三方类库,用于android中请求网络. 这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和Le ...

  10. Qt加载天地图离线api开发包/从官网趴地图js代码/费了九牛二虎之力终于搞定

    一.前言说明 网上关于如何趴天地图离线api文件的文章,只有少量的两三篇,而且几乎没有说全和说对,搞得评论也是一片懵逼,这里不行那你不行,思路可以借鉴就是.索性花了点时间,自己研究了如何从官网一步步趴 ...