*X. P7708「Wdsr-2.7」八云蓝自动机 Ⅰ

摘自 分治与根号数据结构学习笔记 第三部分 莫队 例题 X.。

一道莫队好题。私以为本题最有价值的地方在于对单点修改的转化以及对交换两个数的处理:需要维护原来每个位置现在的位置,以及现在每个位置原来的位置。

注意到这个单点修改并不方便实现(如果是单点加就好做了),我们可以使用一个小技巧将其转化为交换两个数,即新建一个 \(a_c=k\),并将其看做 \(a_x\) 与 \(a_c\) 交换。这一步非常巧妙,因为它消灭了单点修改这一麻烦的操作。

对于多次询问一段区间的操作结果,我们通常需要使用莫队实现,因此考虑区间在伸缩时需要维护什么东西。为了支持在操作序列最前面加入交换两个数的操作,我们不难想到维护:

  • 序列 \(a\) 在操作后变成了什么样。

  • \(pos_i\) 表示现位置 \(i\) 是原来的哪个位置。

  • \(rev_i\) 表示原位置 \(i\) 现在在哪。

  • \(add_i\) 表示原位置 \(i\) 上的数被查询了多少次。

  • 当右端点右移 \(r-1\to r\) 时:

    • 若第 \(r\) 个操作是交换 \(x,y\),则交换 \(a_x,a_y\),\(pos_x,pos_y\),\(rev_{pos_x},rev_{pos_y}\)。
    • 若第 \(r\) 个操作是查询 \(x\),则令 \(ans\gets ans+a_x\),\(add_{pos_x}\gets add_{pos_x}+1\)。
  • 当左端点左移 \(l+1\to l\) 时:

    • 若第 \(l\) 个操作是交换 \(x,y\),注意我们相当于交换 “原位置” 的两个数,因此对答案有影响。令 \(del=a_{rev_y}-a_{rev_x}\),答案需加上 \(del\times (add_x-add_y)\),即计算原来的 \(a_x,a_y\) 即现在的 \(a_{rev_x},a_{rev_y}\) 在交换后的贡献变化量。此外,交换 \(a_{rev_x},a_{rev_y}\) \(add_x,add_y\),\(rev_x,rev_y\) 以及 \(pos_{rev_x},pos_{rev_y}\)。
    • 若第 \(l\) 个操作是查询 \(x\),则令 \(ans\gets ans+a_{rev_x}\),\(add_x\gets add_x+1\),意义显然。

右端点左移和左端点右移的情况分别与上述两种情况相似,不再赘述。时间复杂度 \(\mathcal{O}(n\sqrt n)\)。

const int N=4e5+5;
const int B=666;
uint n,m,q,cnt,a[N],id[N],op[N],x[N],y[N];
struct query{
int l,r,blk,id;
bool operator < (const query &v) const {
return blk!=v.blk?blk<v.blk:blk&1?r>v.r:r<v.r;
}
}c[N]; uint ans,res[N],pos[N],rev[N],add[N];
int main(){
cin>>n>>m,cnt=n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++){
cin>>op[i]>>x[i]; if(op[i]!=3)cin>>y[i];
if(op[i]==1)a[++cnt]=y[i],op[i]=2,y[i]=cnt;
}
for(int i=1;i<=cnt;i++)pos[i]=rev[i]=i;
cin>>q;
for(int i=1,l,r;i<=q;i++)cin>>l>>r,c[i]={l,r,l/B,i};
sort(c+1,c+q+1);
for(int i=1,l=1,r=0;i<=q;i++){
while(r<c[i].r){
r++;
if(op[r]==2){
swap(pos[x[r]],pos[y[r]]),swap(a[x[r]],a[y[r]]);
swap(rev[pos[x[r]]],rev[pos[y[r]]]);
}
else ans+=a[x[r]],add[pos[x[r]]]++;
}
while(l>c[i].l){
l--;
if(op[l]==2){
uint del=a[rev[y[l]]]-a[rev[x[l]]];
swap(rev[x[l]],rev[y[l]]),ans+=(add[x[l]]-add[y[l]])*del;
swap(a[rev[x[l]]],a[rev[y[l]]]);
swap(pos[rev[x[l]]],pos[rev[y[l]]]),swap(add[x[l]],add[y[l]]);
}
else ans+=a[rev[x[l]]],add[x[l]]++;
}
while(r>c[i].r){
if(op[r]==2){
swap(pos[x[r]],pos[y[r]]),swap(a[x[r]],a[y[r]]);
swap(rev[pos[x[r]]],rev[pos[y[r]]]);
}
else ans-=a[x[r]],add[pos[x[r]]]--;
r--;
}
while(l<c[i].l){
if(op[l]==2){
uint del=a[rev[y[l]]]-a[rev[x[l]]];
swap(rev[x[l]],rev[y[l]]),ans+=(add[x[l]]-add[y[l]])*del;
swap(a[rev[x[l]]],a[rev[y[l]]]);
swap(pos[rev[x[l]]],pos[rev[y[l]]]),swap(add[x[l]],add[y[l]]);
}
else ans-=a[rev[x[l]]],add[x[l]]--;
l++;
}
res[c[i].id]=ans;
}
for(int i=1;i<=q;i++)cout<<res[i]<<"\n";
return 0;
}

P7708「Wdsr-2.7」八云蓝自动机 Ⅰ的更多相关文章

  1. 未来科技城 x 奇点云打造「企业数据大脑」,助力1.3万家企业服务

    “当前,政府数字化和数字政府建设已成为一种趋势.一种必然,并且有了一条水到渠成式的实现路径.” 上升为国家战略的数字中国建设加速了”智慧政务“的生动实践,杭州未来科技城的「企业数据大脑」就是一个典型. ...

  2. 报名|「OneAPM x DaoCloud」技术公开课:Docker性能监控!

    如今,越来越多的公司开始 Docker 了,「三分之二的公司在尝试了 Docker 后最终使用了它」,也就是说 Docker 的转化率达到了 67%,同时转化时长也控制在 60 天内. 既然 Dock ...

  3. 看懂「www.google.com」背后的逻辑

    在前两篇文章中,我们完整的描述了计算机网络 OSI 五层模型的相关内容.那么,本篇将会从一个实践案例开始,带你从整体上重新认识我们的计算机网络. 我们以访问 Google 为例,当我们在浏览器地址栏中 ...

  4. 深圳即将启动首届「全国人工智能大赛」:超过 500 万大奖 & 政府资助,潜信息你读懂了吗!

    人工智能加速“视频/视觉”发展,近期,深圳市即将迎来人工智能领域权威赛事之一——首届「全国人工智能大赛」(The First National Artificial Intelligence Chal ...

  5. SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ...

  6. SpringBoot图文教程17—上手就会 RestTemplate 使用指南「Get Post」「设置请求头」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ...

  7. 面试都在问的「微服务」「RPC」「服务治理」「下一代微服务」一文带你彻底搞懂!

    ❝ 文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) ❞ 单体式应用程序 与微服务相对的另一个概念是传统的「单体式应用程 ...

  8. 「查缺补漏」巩固你的RocketMQ知识体系

    Windows安装部署 下载 地址:[https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.5.2/rocketmq-all-4.5.2-bin- ...

  9. Appium常用操作之「Toast提示信息获取」

    坚持原创输出,点击蓝字关注我吧 作者:清菡 博客:Oschina.云+社区.知乎等各大平台都有. 目录 一.什么是 Toast 二.获取 Toast 提示信息的前提 1.针对这种元素,有的时候我们需要 ...

随机推荐

  1. 看动画学算法之:队列queue

    目录 简介 队列的实现 队列的数组实现 队列的动态数组实现 队列的链表实现 队列的时间复杂度 简介 队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构. 想象一下我们日常的排队买票 ...

  2. [敏捷软工团队博客]Beta阶段使用指南

    软件工程教学实践平台使用指南 项目地址:http://20.185.223.195:8000/ 项目团队:the agiles 进入界面如图: 目录 软件工程教学实践平台使用指南 学生端 登录 iss ...

  3. the Agiles Scrum Meeting 6

    会议时间:2020.4.14 20:00 1.每个人的工作 今天已完成的工作 增量组:开发广播正文展开收起功能 issues:增量组:广播正文展开收起功能实现 完善组:修复冲刺部分的bug issue ...

  4. 手把手教你学Dapr - 2. 必须知道的概念

    Sidecar 边车 Dapr API提供Http和gRPC两种通讯方式. 运行方式则可以是容器也可以是进程(Windows开发推荐使用Self Hosted,后续会解释). 这样的好处是与运行环境无 ...

  5. Vue报错 type check failed for prop “xxx“. Expected String with value “xx“,got Number with value ‘xx‘

    vue报错    [Vue warn]: Invalid prop: type check failed for prop "name". Expected String with ...

  6. elasticsearch的索引操作

    1.创建索引(test_index) curl -XPUT "http://192.168.99.1:9200/test_index" 2.创建索引,指定分片和副本的数量 curl ...

  7. 字符串与模式匹配算法(六):Needleman–Wunsch算法

    一.Needleman-Wunsch 算法 尼德曼-翁施算法(英语:Needleman-Wunsch Algorithm)是基于生物信息学的知识来匹配蛋白序列或者DNA序列的算法.这是将动态算法应用于 ...

  8. HBase的安装与部署

    一.部署前置环境 先部署分布式的高可用版的Hadoop,即ZooKeeper+Hadoop. https://www.cnblogs.com/live41/p/15483192.html * 部署的服 ...

  9. VCS常用仿真选项开关及步骤总结

    转自:https://blog.csdn.net/bcs_01/article/details/79803304 转自:https://blog.csdn.net/wonder_coole/artic ...

  10. hdu 2586 How far away? (LCA模板)

    题意: N个点,形成一棵树,边有长度. M个询问,每个询问(a,b),询问a和b的距离 思路: 模板题,看代码.DFS预处理算出每个结点离根结点的距离. 注意: qhead[maxn],而不是qhea ...