luogu P4108 [HEOI2015]公约数数列(分块、gcd性质)
题解链接
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <iostream>
#include <map>using namespace std;
typedef long long ll;
#define INF 2147483648
//#define INF 2147438647
const int N = 407, M = 10007, mod = 998244353;
using namespace std;int gcd(int a, int b)
{if(b == 0)return a;return gcd(b, a % b);
}int n, m, q, u, block_num;
int v[N][N];
int block, bi[N];
int g[N][N];//g[i][j] 表示的是第i块第j个点的前缀gcd,一定是单调递减的,且不同的个数最多为log(ai)个
int G[N];//G[i]表示的是第i块的整块的前缀gcd
int sum[N];//sum[i]表示的是第i块的整块的前缀异或和
map <int, int> f[N];//f[x][tmp] = y;表示的是从第一个点到第x块的前缀异或和为tmp的位置为y
int kcase;void modify(int u)
{int x = (u - 1) / block + 1;int y = (u - 1) % block + 1;scanf("%d", &v[x][y]);f[x].clear();int tmp = 0;g[x][0] = x ? G[x - 1] : 0;//判断边界for(int j = 1; j <= block; ++ j){//整个快的前缀gcd以及前缀异或和都要改变tmp ^= v[x][j];if(f[x].find(tmp) == f[x].end())f[x][tmp] = j;g[x][j] = gcd(v[x][j], g[x][j - 1]);G[x] = g[x][j];}sum[x] = tmp;
}int query(ll k)
{int tmp = 0;int gtmp = v[1][1];//直接暴力跑,如果前缀gcd和上一块相同,直接O(1)查找答案。//如果不相同,暴力找答案。因为不相同的前缀gcd只有log(ai)个,所以可以暴力for(int i = 1; i <= block_num; ++ i){if(!i || G[i] != G[i - 1]){for(int j = 1; j <= block; ++ j){tmp ^= v[i][j];gtmp = g[i][j];if((ll)tmp * gtmp == k){return (i - 1) * block + j - 1;}}}else {gtmp = G[i];//需要判断一下当前值是否小于intif(k % gtmp == 0 && k / gtmp < INF && f[i].find(k / gtmp ^ tmp) != f[i].end()){return (i - 1) * block + f[i][k / gtmp ^ tmp] - 1;}tmp ^= sum[i];}}return -1;
}int main()
{scanf("%d", &n);block = sqrt(n);int tmp = 0;for(int i = 1; i <= n; ++ i){int x = (i - 1) / block + 1;int y = (i - 1) % block + 1;scanf("%d", &v[x][y]);tmp ^= v[x][y];g[x][y] = gcd(v[x][y], g[x][y - 1]);G[x] = g[x][y];//一直更新,直到整个块的最后一个if(f[x].find(tmp) == f[x].end()){//没有就插入f[x][tmp] = y;}if(x != i / block + 1){//该块的最后一个点sum[x] = tmp;//记录整块的前缀异或和g[x + 1][0] = G[x];//细节,必须所有的块都连贯起来tmp = 0;//清零}}scanf("%d", &q);char op[100];block_num = ceil((double)n / block);while(q -- ){scanf("%s", op);if(op[0] == 'M'){scanf("%d", &u);modify(u + 1);//输入的点是从0开始的,我们的点是从1开始的}else {ll k;scanf("%lld", &k);int res = query(k);if(res == -1)puts("no");else printf("%d\n", res);}}return 0;
}
luogu P4108 [HEOI2015]公约数数列(分块、gcd性质)相关推荐
- 【BZOJ4028】[HEOI2015]公约数数列(分块/数量级很小法)
[BZOJ4028][HEOI2015]公约数数列 https://www.luogu.com.cn/problem/P4108 求解最靠前的一个位置前缀gcd和前缀异或的乘积恰好等于x,并且要求支持 ...
- 4028: [HEOI2015]公约数数列
4028: [HEOI2015]公约数数列 Description 设计一个数据结构. 给定一个正整数数列 a_0, a_1, ..., a_{n - 1},你需要支持以下两种操作: 1. MODIF ...
- #6279. 数列分块入门 3(区间修改,查询权值前驱)
#6279. 数列分块入门 3 这是使用hzwer建议的set写的分块代码,set自动排序,支持二分查找,但是常数较大,比我下面写的用vector实现的分块慢了三倍,空间大了10倍. #include ...
- BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay)
BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay) 手动博客搬家: 本文发表于20180825 00:34:49, 原地址https://blog.csdn.ne ...
- LOJ 数列分块入门6
LOJ 数列分块入门6 题目: 题目 题解: 我都不懂这题为什么要用分块... ... 直接vector就好了... 但是如果有区间修改的话就不行了.所以这题是启示我们也可以动态分块.具体就是每次插入 ...
- 算法笔记--数列分块
黄老师的博客http://hzwer.com/8053.html 模板: const int N=1e5+5; int a[N],belong[N]/*属于哪个块*/,blo/*块的大小*/,bloc ...
- LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)
#6280. 数列分块入门 4 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 题目描述 给出一个长为 ...
- 数列分块入门(套题)(loj6277,loj6278,loj6279,loj6280,loj6281,loj6282,loj6283,loj6284,loj6285)
前言 zjoi考差了,码一些分块题缓解一下心情 壹 数列分块入门 1[loj6277] 题目大意:区间加,单点查 直接分块,区间加时完全覆盖的块打tag,边界块暴力重构 块大小设为n\sqrt nn ...
- 数列分块入门 (1 ~ 7)
分块 6277. 数列分块入门 1 分块思想 我们把每m个元素分成一块,所以我们总共的块数就是n/mn / mn/m块,一般情况下我们取m=nm = \sqrt{n}m=n.对于区间加操作,我们可以 ...
最新文章
- FTP资源下检测URL地址下文件大小
- 程序局部性原理的一些思考
- python123平台作业答案第十一周_第十一周作业
- 初学python之路-day04
- (十一)linux之poll轮询
- 【Bootstrap】 bootstrap-table表格组件
- extjs 月份选择控件_Ext DateField控件 - 只选择年月
- php增加vip等级设置,xiu主题添加vip等级评论样式
- spring cloud gateway 之限流篇
- echarts自定义y轴刻度信息
- 打开word时总是弹出The resource dll can not be loaded
- Ps 初学者教程,如何用文字增强您的照片?
- android selector 开始自定义样式
- Iphone 开发常用代码
- 金盾播放器android安卓,金盾高级视频加密系统跨平台播放器Android安卓安装步骤.doc...
- 模拟高清和数字高清摄像机的区别,全局快门CMOS 图像传感器,Interline Transfer CCD图像传感器
- 操作系统之调度 (十) --- 处理机调度、高级调度、中级调度、低级调度...
- 计算机色彩知识调研(二):位深、Gamma值、标准色温和Display P3
- 在输入框输入时限制输入框只能输入正整数以及两位小数正则表达式
- 《人性的弱点》简明总结