luogu P4108 [HEOI2015]公约数数列——solution
-by luogu
不会啊....
然后%了一发题解,
关键是
考虑序列{$a_n$}的前缀gcd序列,
它是单调不升的,且最多只会改变$log_2N$次,因为每变一次至少除2
于是,当我们询问x时:
对每一段满足前缀gcd不变的部分;
可以用map之类的直接查询这个区间中前缀xor值等于$x\over gcd$的最小下标;
但我们还有单点修改,
考虑分块,——随便分个根号块就好
对每块
维护块从左端到右端元素的xor和,
维护块中左端到右端元素的gcd值,
对每个元素
维护从他所在块的左端点到他自己的xor和与gcd值;
这样修改只影响一块之内的所有元素的相关值和这一块的相关值;
对每块开个map
把左端到每个元素的xor值插到对应块的map中去;
当我们查询x时
枚举每块,
如果到这块之前的前缀gcd等于加入这块之后的前缀gcd(设为gcd),则意味着这块之内(从左端到右端)的所有点的前缀gcd都相等,(前缀gcd单调不升)
这样的话,我们设到这块之前的xor为$XOR_{0,L-1}$我们只需在这块的map中查是否有某个$XOR_{l~i}$值满足$gcd*(XOR_{0,L-1}xorXOR_{l,i})=x$即可,其效率为map的效率,$O(log_2\sqrt{N})$乘上块数即为$O(\sqrt{N}log_2\sqrt{N})$
反之,则暴力枚举这块中的每个元素即可,这种情况不超过log次,其总效率为$O(\sqrt{N}log_2{N})$
至于修改,则直接把对这块所维护的信息重新维护即可即可,块大小为$\sqrt{N}$乘上map的效率为$O(\sqrt{N}log_2\sqrt{N})$
于是其总复杂度为$O(q\sqrt{N}log_2N)$
代码:
#include<map>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
map <int ,int >MP[];
int a[];
int b_size,b_num;
int L[];
int b_gcd[],b_xor[];
int a_gcd[],a_xor[];
int n,q;
char s[];
int GCD(int ,int );
void modify();
void query();
int main()
{
int i,j,k;
scanf("%d",&n);
b_size=sqrt(n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
for(b_num=i=;i<=n;b_num++,i+=b_size){
L[b_num]=i;
a_xor[i]=a_gcd[i]=a[i];
MP[b_num].insert(pair<int ,int >(a_xor[i],i));
for(j=i+;j<i+b_size&&j<=n;j++){
a_xor[j]=a_xor[j-]^a[j];
a_gcd[j]=GCD(a_gcd[j-],a[j]);
MP[b_num].insert(pair<int ,int >(a_xor[j],j));
}
b_xor[b_num]=a_xor[j-],b_gcd[b_num]=a_gcd[j-];
}
scanf("%d",&q);
for(i=;i<=q;i++){
scanf("%s",s);
if(s[]=='M')
modify();
else
query();
}
}
int GCD(int a,int b){
if(!b)return a;
return GCD(b,a%b);
}
void modify(){
int id,x,i,j,k;
scanf("%d%d",&id,&x),id++;
for(i=j=;j<=n;j+=b_size,i++)
if(j+b_size>id)
break;
MP[i].clear();
a[id]=x;
a_xor[(i-)*b_size+]=a_gcd[(i-)*b_size+]=a[(i-)*b_size+];
MP[i].insert(pair<int ,int >(a_xor[(i-)*b_size+],(i-)*b_size+));
for(j=(i-)*b_size+;j<=i*b_size&&j<=n;j++){
a_xor[j]=a_xor[j-]^a[j];
a_gcd[j]=GCD(a_gcd[j-],a[j]);
MP[i].insert(pair<int ,int >(a_xor[j],j));
}
b_xor[i]=a_xor[j-],b_gcd[i]=a_gcd[j-];
}
void query(){
LL x,xx;
map <int ,int >::iterator iter;
int i,j,k,lasxor=,nowgcd=,lasgcd=;
scanf("%lld",&x);
for(i=;i<=b_num;i++){
nowgcd=GCD(b_gcd[i],lasgcd);
if(nowgcd==lasgcd){
if(x%lasgcd){
lasgcd=nowgcd,lasxor^=b_xor[i];
continue;
}
xx=x/lasgcd;
xx^=lasxor;
if(xx>0x7fffffff){
lasgcd=nowgcd,lasxor^=b_xor[i];
continue;
}
k=xx;
if(MP[i].count(k)==){
iter=MP[i].find(k);
printf("%d\n",iter->second-);
return ;
}
}
else{
for(j=(i-)*b_size+;j<=n&&j<=i*b_size;j++)
if(1ll*(lasxor^a_xor[j])*GCD(lasgcd,a_gcd[j])==x){
printf("%d\n",j-);
return ;
}
}
lasgcd=nowgcd,lasxor^=b_xor[i];
}
printf("no\n");
}
分块还差得远呢
luogu P4108 [HEOI2015]公约数数列——solution的更多相关文章
- 【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 ...
- 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 ...
- 洛谷 P4108 / loj 2119 [HEOI2015] 公约数数列 题解【分块】
看样子分块题应该做的还不够. 题目描述 设计一个数据结构. 给定一个正整数数列 \(a_0, a_1, \ldots , a_{n-1}\),你需要支持以下两种操作: MODIFY id x: 将 \ ...
- bzoj4028: [HEOI2015]公约数数列
Description 设计一个数据结构. 给定一个正整数数列 a_0, a_1, ..., a_{n - 1},你需要支持以下两种操作: 1. MODIFY id x: 将 a_{id} 修改为 x ...
- bzoj 4028 : [HEOI2015]公约数数列
之前看了好几次都没什么思路,今天下定决心把这题切了. 观察到$0-x$的gcd最多变化log次,因为它每次变化一定至少要去掉一个质因子,所以我们可以枚举gcd. 因为数据范围比较小,所以想到了分块. ...
- [HEOI2015]公约数数列
不错的分块题 gcd和xor其实并没有联系 这里,xor的按位性质没有半点卵用 gcd的性质却很关键: 一个数组,前缀gcd最多logn个不同的 gcd不太多,(暴力的基础) 所有考虑分块. 分块,每 ...
- [BZOJ4028][HEOI2015]公约数数列(分块)
先发掘性质: 1.xor和gcd均满足交换律与结合率. 2.前缀gcd最多只有O(log)个. 但并没有什么数据结构能同时利用这两个性质,结合Q=10000,考虑分块. 对每块记录这几个信息: 1.块 ...
随机推荐
- Doxygen的使用,配置及实例
Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,可以从一套归档源文件开始,生成文档 下载Doxygen + Graphviz Doxygen可以生成动态文档 Graphviz ...
- ajaxsubmit 上传文件 在IE中返回的内容 提示下载文件
在ajaxSubmit提交表单的时候,如果表单内有文件上传的话,会判断参数是否配置的iframe为false参数,如果没有,会用创建隐藏iframe方式提交表单,如果设定了iframe为false,则 ...
- 数据库相关 Mysql基本操作
数据库相关 设计三范式: 第一范式: 主要强调原子性 即表的每一列(字段)包含的内容,不能再拆分.如果,某张表的列,还可以细分,则违背了数据库设计的第一范式. 第二范式: 主要强调主键,即:数据库中的 ...
- 在Ubuntu 16.04上利用Jexus+.Net Core+Linux版SQL Server部署ZKEACMS.Core
百度传课视频地址:https://chuanke.baidu.com/v5849090-223278-1498090.html 一.SQL Server on Linux的安装 官方文档:https: ...
- docker学习实践之路[第五站]mysql镜像应用
拉取mysql镜像 docker pull mysql:5.6 #拉取mysql .6版本的镜像 运行mysql镜像 docker run --name some-mysql --restart=al ...
- 课程三(Structuring Machine Learning Projects),第一周(ML strategy(1)) —— 1.Machine learning Flight simulator:Bird recognition in the city of Peacetopia (case study)
[]To help you practice strategies for machine learning, the following exercise will present an in-de ...
- Win7上Spark WordCount运行过程及异常
WordCount.Scala代码如下: package com.husor.Spark /** * Created by huxiu on 2014/11/26. */ import org.apa ...
- c++的动态绑定和静态绑定
为了支持c++的多态性,才用了动态绑定和静态绑定. 1.对象的静态类型:对象在声明时采用的类型.是在编译期确定的. 2.对象的动态类型:目前所指对象的声明.在运行期决定.对象的动态类型可以更改,但是静 ...
- storm_分组策略
注意1:原始的案例 spout 和bolt都是1个并发 所以文件中30条日志 从spout发出以后 bolt接受到30条
- bower 和 npm 的区别
前端技术和工程实践真的是突飞猛进啊,想当年,我这个半业余前端吭哧吭哧做页面的时候,哪有这么多东西可以用啊,现在先进到我都完全看不懂了.本文主要讲一下同是包管理器的bower和npm的差别. 主要也是在 ...