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.块 ...
随机推荐
- Python-flask跨站请求伪造和跨站请求保护的实现
图中 Browse 是浏览器,WebServerA 是受信任网站/被攻击网站 A,WebServerB 是恶意网站/点击网站 B. (1) 一开始用户打开浏览器,访问受信任网站 A,输入用户名和密码登 ...
- mysql创建账号及管理权限
mysql创建账号及管理权限 0.mysql版本8.0.15,服务器版本:RHEL 6.5 1.创建用户名密码 mysql> use mysql; mysql> create user ' ...
- flaks___git
今天呢 我给大家分享一个超实用的一个把代码分享到云端的一种操作 比如我们在家里,要想做项目的话可以直接从云端上拉取下来代码直接开始工作了 而且还可以随时修改,没有地点的局限性了,只要你想敲,随时随地 ...
- 09-01 Java final,多态,抽象类,接口
final /* final可以修饰类,方法,变量 特点: final可以修饰类,该类不能被继承. final可以修饰方法,该方法不能被重写.(覆盖,复写) final可以修饰变量,该变量不能被重新赋 ...
- python实战问题记录
开发环境搭建 1.安装aiohttp这个异步的http框架失败 提示使用pip更高版本,但是更新之后,还是无法使用.所以,我们采用anaconda中的aiohttp,即打开anaconda,然后进入E ...
- inotify监听文件夹的变动
inotify只能监控单层目录变化,不能监控子目录中的变化情况.如果需要监控子目录,需要在调用inotify_add_watch(int fd, char *dir, int mask):int建立监 ...
- 前端通信:ajax设计方案(八)--- 设计请求池,复用请求,让前端通信快、更快、再快一点
直接进入主题,本篇文章有点长,包括从设计阶段,到摸索阶段,再到实现阶段,最后全面覆盖测试阶段(包括数据搜集清洗),还有与主流前端通信框架进行对比PK阶段. 首先介绍一下一些概念: 1. 浏览器的并发能 ...
- 记一次解决CSS定位bug思路
事因 网站中的遮罩层大都有一个问题,就是在这个遮罩层中滑动,里面的内容也会跟着滑动,我是这样想的,既然都有这个问题,干脆写一个通用的插件出来,省的每个还得单独处理.如果是单独处理这个问题是比较好解决的 ...
- gson和fastjson
实体类转string的时候gson会对 & 进行url编码; fastjson不会
- 微信小程序开发语言的选择
微信使用的开发语言和文件很「特殊」. 小程序所使用的程序文件类型大致分为以下几种: ①WXML(WeiXin Mark Language,微信标记语言) ②WXSS(WeiXin Style Shee ...