【HEOI2015】公约数数列 题解(分块)
前言:毒瘤数据结构题,半个下午都在搞它了……
---------------------------
题目大意:给定一个长度为$n$的序列,有两种操作:1.把$a_x$的值改成$y$。2.求一个最小的$p$使得$gcd(a_0,a_1,\cdots ,a_p)*XOR(a_0,a_1,\cdots ,a_p)=x$。
------------------------------
这种数据结构题一般只能用分块解决。线段树什么的不得T飞……
对于每个块,我们维护块内的$gcd$和$xor$和,还要记录以每个块的左端点为左端点的$xor$前缀和。
修改的时候直接$\sqrt n$暴力把所属块内的信息重新修改。
重点是查询。我们维护一个$pregcd$和$prexo$表示已经询问过的部分的$gcd$和$xor$和。有两种情况:
1.如果$gcd(pregcd,gcd[i])=pregcd$,那么二分查找块内可能符合条件的$p$。可以参考代码来理解。
2.如果不相等,那么暴力查找块内可能的$p$。
有一个性质:$A xor B=C$,那么$C xor B=A$。可以利用这个性质进行查询。
时间复杂度$O(n\sqrt n \log n)$。
代码:
/*记录每个块内的gcd,xor和;记录以每个块左端点为左端点的前缀xor和*/
#include<bits/stdc++.h>
#define int long long
using namespace std;
int gcd[],sumxo[],n,m,a[],block,tot,pregcd,prexo;
struct node{int sum,id;}xo[];
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline int GCD(int x,int y){if (!y) return x;return GCD(y,x%y);}
bool cmp(node x,node y){if(x.sum==y.sum) return x.id<y.id;return x.sum<y.sum;}
inline void build(int i)
{
gcd[(i-)*block+]=sumxo[(i-)*block+]=a[(i-)*block+];
xo[(i-)*block+]=(node){sumxo[(i-)*block+],(i-)*block+};
for (int j=(i-)*block+;j<=min(n,i*block);j++)
{
gcd[j]=GCD(gcd[j-],a[j]);
sumxo[j]=sumxo[j-]^a[j];
xo[j]=(node){sumxo[j],j};
}
sort(xo+(i-)*block+,xo+min(n,i*block)+,cmp);
}
inline int half(int l,int r,int x)
{
int mid,res=l;
while(l<=r)
{
mid=(l+r)>>;
if (xo[mid].sum>=x) res=mid,r=mid-;
else l=mid+;
}
return res;
}
inline int query(int x)
{
int ans=-;
pregcd=a[],prexo=;
for (int i=;i<=tot&&ans==-;i++)
{
if (GCD(pregcd,gcd[min(n,i*block)])==pregcd)
{
if (x%pregcd==)
{
int k=(x/pregcd)^prexo;
int pos=half((i-)*block+,min(n,i*block),k);
if(xo[pos].sum==k)
{
ans=xo[pos].id;
break;
}
}
pregcd=GCD(pregcd,gcd[min(n,i*block)]),prexo^=sumxo[min(n,i*block)];
}
else
{
for (int j=(i-)*block+;j<=min(n,i*block);j++)
{
pregcd=GCD(pregcd,a[j]);prexo^=a[j];
if (pregcd*prexo==x){
ans=j;
break;
}
}
if (ans!=-) break;
}
}
return ans;
}
signed main()
{
n=read();block=sqrt(n);
tot=n/block;if (n%block) tot++;
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=tot;i++) build(i);
m=read();
while(m--)
{
string s;cin>>s;
if (s[]=='M')
{
int x=read(),y=read();x++;
a[x]=y;
build((x-)/block+);
}
else
{
int x=read();
int s=query(x);
if (s==-) printf("no\n");
else printf("%lld\n",s-);
}
}
return ;
}
【HEOI2015】公约数数列 题解(分块)的更多相关文章
- 【BZOJ4028】[HEOI2015]公约数数列(分块)
[BZOJ4028][HEOI2015]公约数数列(分块) 题面 BZOJ 洛谷 题解 看一道题目就不会做系列 首先\(gcd\)最多只会有\(log\)种取值,所以我们可以暴力枚举出所有可能的\(g ...
- BZOJ 4028: [HEOI2015]公约数数列 【分块 + 前缀GCD】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=4028 4028: [HEOI2015]公约数数列 Time Limit: 10 Sec ...
- 洛谷 P4108 / loj 2119 [HEOI2015] 公约数数列 题解【分块】
看样子分块题应该做的还不够. 题目描述 设计一个数据结构. 给定一个正整数数列 \(a_0, a_1, \ldots , a_{n-1}\),你需要支持以下两种操作: MODIFY id x: 将 \ ...
- BZOJ4028 HEOI2015公约数数列(分块)
前缀gcd的变化次数是log的,考虑对每一种gcd查询,问题变为查询一段区间是否存在异或前缀和=x/gcd. 无修改的话显然可以可持久化trie,但这玩意实在没法支持修改.于是考虑分块. 对于每一块将 ...
- BZOJ 4028: [HEOI2015]公约数数列 分块
4028: [HEOI2015]公约数数列 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4028 Description 设计一个数据结 ...
- 【BZOJ4028】[HEOI2015]公约数数列 分块
[BZOJ4028][HEOI2015]公约数数列 Description 设计一个数据结构. 给定一个正整数数列 a_0, a_1, ..., a_{n - 1},你需要支持以下两种操作: 1. M ...
- [BZOJ4028][HEOI2015]公约数数列(分块)
先发掘性质: 1.xor和gcd均满足交换律与结合率. 2.前缀gcd最多只有O(log)个. 但并没有什么数据结构能同时利用这两个性质,结合Q=10000,考虑分块. 对每块记录这几个信息: 1.块 ...
- bzoj4028: [HEOI2015]公约数数列
Description 设计一个数据结构. 给定一个正整数数列 a_0, a_1, ..., a_{n - 1},你需要支持以下两种操作: 1. MODIFY id x: 将 a_{id} 修改为 x ...
- luogu P4108 [HEOI2015]公约数数列——solution
-by luogu 不会啊.... 然后%了一发题解, 关键是 考虑序列{$a_n$}的前缀gcd序列, 它是单调不升的,且最多只会改变$log_2N$次,因为每变一次至少除2 于是,当我们询问x时: ...
随机推荐
- 重学 Java 设计模式:实战模版模式「模拟爬虫各类电商商品,生成营销推广海报场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 黎明前的坚守,的住吗? 有人举过这样一个例子,先给你张北大的录 ...
- day03总结
一. 基本数据类型# 1.整型int# 作用:记录年龄.等级.号码等状态# 定义与使用# age = 999# level = 10# qq = 383838338 # res=age * 1# pr ...
- TP5中的缓存使用
Thinkphp 5.0采用了 think\Cache 类来提供缓存支持 缓存支持采用驱动方式,所以缓存在使用之前,需要进行连接操作,也就是缓存初始化操作. 支持的缓存类型包括file.memcach ...
- 数据可视化基础专题(五):Pandas基础(四) 生成对象
引言 先介绍下 Pandas 的数据结构,毕竟数据结构是万物的基础. Pandas 有两种主要的数据结构: Series 和 DataFrame 模块导入 首先我们在代码中引入 Pandas 和 Nu ...
- python生成器原理剖析
python生成器原理剖析 函数的调用满足"后进先出"的原则,也就是说,最后被调用的函数应该第一个返回,函数的递归调用就是一个经典的例子.显然,内存中以"后进先出&quo ...
- 保存与恢复变量和模型,tensorflow官方文档阅读笔记
官方中文文档的网址先贴出来:https://tensorflow.google.cn/programmers_guide/saved_model tf.train.Saver 类别提供了保存和恢复模型 ...
- 《重学 Java 设计模式》PDF 出炉了 - 小傅哥,肝了50天写出18万字271页的实战编程资料
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! @ 目录 一.前言 二.简介 1. 谁发明了设计模式? 2. 我怎么学不会设计模式? 3. 适 ...
- 测试工程师想进BAT必须具备的几项素质
我发现一个奇怪的现象:总是听到身边的程序员朋友谈论BAT(中国大陆互联网的三大巨头:百度.阿里.腾讯)以及如何进入BAT,却鲜少有测试会去谈论或者考虑这些问题. 我不知道这是为什么,或者我就算知道也只 ...
- 从LocalDateTime序列化探讨全局一致性序列化
日拱一卒无有尽,功不唐捐终入海. 楔子 前两周发了三篇SpringSecurity和一篇征文,这周打算写点简单有用易上手的文章,换换脑子,休息一下. 今天要写的是这篇:从LocalDateTime序列 ...
- Flutter + Android 混合开发
JIT (Just In Time) 即时编译器, 边执行边编译 程序运行时,JIT 编译器选择将最频繁执行的方法编译成本地代码.运行时才进行本地代码编译而不是在程序运行前进行编译 AOT可以理解为“ ...