hdu 5381 莫队算法/gcd

HDU 5381 The sum of gcd (2015年多校比赛第8场) 1.题目描述:点击打开链接 2.解题思路:本题利用莫队算法解决。由于是第一次学习这个算法,因此研究了比较长的一段时间才弄懂。首先,莫队算法解决的问题是无修改的离线区间查询问题。该算法实际上是由曼哈顿距离最小生成树演变来的,由于要处理m个区间,可以将这m个区间看做二维平面上的点,那么处理这m个区间就等价于让这m点连通,且总的转移代价最小。这其实就是一个曼哈顿距离最小生成树问题。 经典的曼 阅读详情

The sum of gcd

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 645    Accepted Submission(s): 279


Problem Description
You have an array A ,the length of A is n
Let f(l,r)=∑ri=l∑rj=igcd(ai,ai+1....aj)
 

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
First line has one integers n
Second line has n integers Ai
Third line has one integers Q ,the number of questions
Next there are Q lines,each line has two integers l , r
1≤T≤3
1≤n,Q≤104
1≤ai≤109
1≤l<r≤n
 

Output
For each question,you need to print f(l,r)
 

Sample Input
  
2 5 1 2 3 4 5 3 1 3 2 3 1 4 4 4 2 6 9 3 1 3 2 4 2 3
 

Sample Output
  
9 6 16 18 23 10
 

Author
SXYZ
 

Source
 


 
区间查询问题,考虑离线的做法。这题关键点是,假如已知k个数a1,...,ak的gcd,那么在原来k个数基础上加多一个数,也就是a1,...ak+1,k+1个数的gcd,要么不变,要么就是至少少了一个因数,而最小的因数就是2,相当于至少变为原来的一半。也就是说1-n个数的gcd最多变了logn次。那么到以第i个数结尾的gcd前面最多可以分为logn段,每一段内gcd相同。有了这个能在logn时间内求出第i个数对前面任意以i结尾的区间的答案的贡献。也是就是知道了[l,r],能在logn内知道[l,r+1]和[l,r-1]。这个时候就可以用莫队算法了。

在网上找了很多莫队算法的资料,感觉就这个最好懂Mo's algorithm  

这场多校是中学生出的。。。应该是之前中学生被人抱怨出题太难,所以这题数据范围放小了,常数小的O(n^2)算法就能800ms水过。。(每次处理出第r个数的logn段gcd区间直接向前遍历一遍更新所有[i,r]的答案),莫队算法只用180ms


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
typedef pair<int, int> P;
typedef long long LL;
#define fir first
#define sec second
const int maxn=1e5+10;

int n,m,a[maxn];
int siz,num;

struct Query
{
    int l, r, id;
    int st;
    bool operator < (const Query& a) const
    {
        return st!=a.st ? st<a.st : r<a.r;
    }
};

Query q[maxn];
vector<P> seg[maxn], segr[maxn];

int gcd(int a, int b)
{
    int tmp;
    while(b){
        tmp=a%b;
        a=b;
        b=tmp;
    }
    return a;
}

LL ans[maxn];

int main()
{
    int t;
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=0; i<=n; i++) seg[i].clear(), segr[i].clear();
        for(int i=0; i<n; i++) scanf("%d", a+i);
        siz=sqrt(n);
        num=(n+siz-1)/siz;

        cin>>m;
        for(int i=0; i<m; i++){
            scanf("%d%d", &q[i].l, &q[i].r);
            q[i].l--; q[i].r--;
            q[i].id=i;
            q[i].st=q[i].l/siz;
        }
        sort(q, q+m);


        for(int i=0; i<n; i++){
            if(i)
            for(int j=0; j<seg[i-1].size(); j++){
                int v=gcd(seg[i-1][j].sec, a[i]);
                int tot=seg[i].size();
                if(tot && seg[i][tot-1].sec==v)
                    seg[i][tot-1].fir=seg[i-1][j].fir;
                else
                    seg[i].push_back(P(seg[i-1][j].fir, v));
            }
            int tot=seg[i].size();
            if(tot && seg[i][tot-1].sec==a[i])
                seg[i][tot-1].fir=i;
            else seg[i].push_back(P(i, a[i]));
        }

        for(int i=n-1; i>=0; i--){
            for(int j=0; j<segr[i+1].size(); j++){
                int v=gcd(segr[i+1][j].sec, a[i]);
                int tot=segr[i].size();
                if(tot && segr[i][tot-1].sec==v)
                    segr[i][tot-1].fir=segr[i+1][j].fir;
                else
                    segr[i].push_back(P(segr[i+1][j].fir, v));
            }
            int tot=segr[i].size();
            if(tot && segr[i][tot-1].sec==a[i])
                segr[i][tot-1].fir=i;
            else segr[i].push_back(P(i, a[i]));
        }

        int l=0,r=0;
        LL val=a[0];
        for(int i=0; i<m; i++){
            while(r<q[i].r){
                r++;
                for(int j=seg[r].size()-1; j>=0; j--){
                    if(j &&l<=seg[r][j-1].first){
                        val+=(LL)seg[r][j].sec*(seg[r][j].fir-seg[r][j-1].fir);
                    }
                    else{
                        val+=(LL)seg[r][j].sec*(seg[r][j].fir-l+1);
                        break;
                    }
                }
            }

            while(r>q[i].r){
                for(int j=seg[r].size()-1; j>=0; j--){
                    if(j &&l<=seg[r][j-1].fir){
                        val-=(LL)seg[r][j].sec*(seg[r][j].fir-seg[r][j-1].fir);
                    }
                    else{
                        val-=(LL)seg[r][j].sec*(seg[r][j].fir-l+1);
                        break;
                    }
                }
                r--;
            }

            while(l<q[i].l){
                for(int j=segr[l].size()-1; j>=0; j--){
                    if(j &&r>=segr[l][j-1].fir){
                        val-=(LL)segr[l][j].sec*(segr[l][j-1].fir-segr[l][j].fir);
                    }
                    else{
                        val-=(LL)segr[l][j].sec*(r-segr[l][j].fir+1);
                        break;
                    }
                }
                l++;
            }

            while(l>q[i].l){
                l--;
                for(int j=segr[l].size()-1; j>=0; j--){
                    if(j &&r>=segr[l][j-1].fir){
                        val+=(LL)segr[l][j].sec*(segr[l][j-1].fir-segr[l][j].fir);
                    }
                    else{
                        val+=(LL)segr[l][j].sec*(r-segr[l][j].fir+1);
                        break;
                    }
                }
            }
            ans[q[i].id]=val;

        }

        for(int i=0; i<m; i++)
            printf("%I64d\n", ans[i]);

    }
    return 0;
}





HDU 5381 The sum of gcd 询问区间内所有子区间的GCD和 [莫队算法] 预处理+莫队,需要抓住 gcd 的本质。 阅读详情

相关推荐

西门子PLC1200与CB1241模块的Modbus RTU从站配置全流程(附串口调试技巧)

本文详细介绍了西门子S7-1200 PLC与CB1241通信模块实现Modbus RTU从站配置的全流程,包括硬件接线规范、TIA Portal工程组态、通信指令编程及串口调试技巧。通过实战案例和常见错误处理方案,帮助工程师快速搭建稳定的工业通信系统,提升自动化设备的互联互通能力。

weixin_29165725的博客 325

HDU5381(莫队算法+ST维护)

解题思路:写了两个小时才写出来,代码能力还有待加强。这道题一开始使用ST表进行维护,用于查询区间范围内的gcd值。但是莫队算法移动一格还有很多区间gcd累加的,要是一个个加必定超时。但是我们可以看出在一定范围内有不少区间的gcd值是一样的,不必一个个数,所以用二分搜索的方式查找,复杂度为O(logn)。我一开始没有事先记录下vl和vr(相同节点),而是要用的时候再查询,这样,复杂度就变成O(log...

qq_39861441的博客 367

宽带阻抗匹配的工程实现-第一步,端口驻波仿真

其实阻抗匹配我工作以来经常说,也经常做,但是基本上都是直接在印制板上进行调试。现在想先用仿真软件直接设计出来,才发现很多东西嘴上说容易,想做出来太难了。所以准备写一些文章,记录一下碰到的问题。

pp_0604的博客 2376

hdu-5213(莫队算法)

莫队算法介绍: 莫队算法是离线处理一类区间不修改查询类问题的算法。就是如果你知道了[L,R]的答案。你可以在O(1)的时间下得到[L,R-1]和[L,R+1]和[L-1,R]和[L+1,R]的答案的话。就可以使用莫队算法。 莫队算法预先知道了所有的询问。可以合理的组织计算每个询问的顺序以此来降低复杂度。要知道我们算完[L,R]的答案后现在要算[L',R']的答案。由于可以在O(1)的时间下

AC之路 1078

Spring AI Alibaba Skill 实战:定义、注册与渐进式披露的企业级落地

摘要:很多团队在接入大模型时,第一步做到的是“能对话”,第二步遇到的瓶颈却是“不能可靠执行”。Skill 的本质不是给模型多几个函数,而是把企业系统中的可控能力,以可治理、可审计、可扩展的方式交给 Agent。本文围绕 Spring AI Alibaba Skill 的定义、注册与渐进式披露,结合电商客服与售后场景,系统讲清楚其底层原理、架构设计、生产级实现、高并发治理与工程实践。@Component@Tool(description = "根据订单号查询订单状态、支付状态和物流状态")扫描包含。

一起修行,不孤单。这里有编程语言、开发工具、学习方法论和踩坑笔记。用简单的话说复杂的事,陪你从小白到进阶。周更干货,欢迎一起成长! 623

PicoRV32 笔记 05

PicoRV32 本地总线接口

jjinl的专栏 1574

hdu 5381 莫队...

The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 854    Accepted Submission(s): 363 Problem Description You have an a

' 泪 添 无 言's blog 552

时序基础模型Timer-S1:十亿参数如何革新时间序列预测

时间序列预测是数据分析与机器学习中的核心任务,旨在基于历史数据预测未来趋势。其原理在于捕捉数据中的趋势、周期性和季节性等时序依赖关系。这项技术的价值在于赋能业务决策,广泛应用于金融风控、能源管理、物联网监控和供应链优化等关键场景。传统方法依赖针对特定任务的专用模型,面临泛化能力弱和开发成本高的挑战。本文聚焦的时序基础模型,通过在海量跨领域数据上进行预训练,学习时序通用模式,并结合十亿级参数带来的强大容量,实现了性能的显著突破。这种范式转变,使得模型能够像“全科医生”一样,通过少量数据微调即可快速适应新任务,

weixin_29164843的博客 269

HDU5381【莫队算法+区间GCD特性】

前言: 主要最近在刷莫队的题,这题GCD的特性让我对莫队的使用也有了新的想法。给福利:神犇的一套莫队算法题 先撇开题目,光说裸的一个莫队算法,主要的复杂度就是n*sqrt(n)对吧,这里我忽略了一个左端点(增加/删除)或者右端点(增加/删除)的所带来的复杂度, 之前也遇到过卡这里的复杂度,但是是因为简单的long long计算多而造成了复杂度增大,从而转变一下。 回到这道题:给...

weixin_30823683的博客 225

Three 之 three.js (webgl)绘制物体模型尺寸虚线包围框工具简单封装 DashLinesBoxTool

Three js 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。本节介绍, three.js (webgl) 中绘制物体模型尺寸虚线包围框工具简单封装 DashLinesBoxTool,主要是给实物绘制线框,有点像AI 识别正方形包裹框的效果。其中,如果有不足之处,欢迎指出,或者你有更好的方法,欢迎留言。

仙魁XAN 2106

18-XLINX的XC7A100T的BANK0引脚说明

DXP_0和 DXN_0是纯输入引脚,Xilinx Artix-7 FPGA 内部集成的一个片上监控模数转换器​ 的差分模拟输入对,模数转换器​的模拟信号输入端,将外部的模拟电压​ 采样并转换为内部的数字值,是一个单向的信号采集过程。它是与 VCCADC配对的关键引脚,共同为内部的精密模数转换器提供一个纯净、安静、独立的参考地平面。多FPGA同步配置: 在多FPGA系统中,主FPGA配置完成后,可以拉低从FPGA的 INIT_B使其等待,等所有FPGA都准备好后,再同时释放,实现同步启动。

weixin_44479192的博客 232

HDU - 5145 莫队算法

题意:有n个女生,每个女生都属于一个教室,现在要访问这些女生,就要进入教室,每次进入一个教室只能访问该教室的一个女生,现在要问对于[L,R]之间的女生全部访问,一共有多少种不同的访问教室的方式?思路:仔细想一下,因为最后的方案按照教室的不同来划分,那就与教室内部的女生访问顺序没有关系,那么只要拿所有女生的访问的排列数除以每个教室女生的排列数即可。 区间查询问题,不涉及修改操作,而且区间改变一个单位

Bahuia的博客 519

手把手教你学simulink(26.7)--控制算法场景示例:基于模型预测控制(MPC)的智能温室环境控制系统

首先,我们需要将温室环境的动力学模型转换为状态空间形式。假设我们有四个状态变量:温度 TT、湿度 HH、光照强度 II 和二氧化碳浓度 CCO2CCO2​,以及四个控制输入:加热器功率 u1u1​、加湿器加湿量 u2u2​、通风扇风速 u3u3​ 和补光灯光照强度 u4u4​。状态空间模型可以表示为:x(t)=[T(t),H(t),I(t),CCO2(t)]Tx(t)=[T(t),H(t),I(t),CCO2​(t)]T 是状态向量。

MHD0815的博客 400

HDU5381 莫队 gcd 预处理

题目链接:HDU 5381 题意:给出N个数,M个询问,对于每个询问,有一组[L,R],输出这个区间内所有子区间的GCD和。 思路:看完题目不难想到莫队,本来转移的时候想着可以rmq套个二分,然而超时了… 看了下别人题解才发现可以先预处理. 至于为什么可以这样预处理.我们发现 gcdgcdgcd 发生变化的话其值至少除2,因此种类顶多就 lognlog nlogn 种,预处理时间复杂度也就 O(n...

qq_40728222的博客 232

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

hdu 5381 The sum of gcd 莫队算法+区间gcd

题意: 略 思路: 杰哥说这种题他都做烂了。。。。orz 对于每个a[i]值,我们处理出以a[i]为起点,分别往左边和往右边的gcd区间的情况(gcd区间个数不会超过log(a[i])个,简单解释就是gcd相同的可以合并,且随着区间扩大,若gcd值不同,则每次至少除以2)。 a[i+1]的gcd区间可以由a[i]的情况推出,遇到可以合并的区间(gcd相等)就合并掉。 例如 2 3

1089

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

HDU 5381 The sum of gcd 莫队暴力

链接 题解链接:http://www.cygmasot.com/index.php/2015/08/15/hdu_5381/ 题意: 给定n长的序列 下面n个数给出这个序列 m个询问 下面m行给出询问的区间。 对于一个询问,输出这个区间内的任意子段的gcd 和。 思路: 因为一个数的gcd只会不变或下降,下降一次至少减半,下降至多32次,所以处理出每个数连续相同的gcd的区间。 然后暴力跑莫队。 #pragma comment(linker, "/STACK:1

九野的博客 2636

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

HDU - 5381 The sum of gcd 莫队

HDU - 5381 首先我们可以观察出从一个点开始的连续gcd最多只有log个, 因为gcd每次最少除2, 然后我们暴力莫队转移就好啦。 #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi...

131

hdu 5381 The sum of gcd 莫队 + DP

第一次用莫队A题。 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5381 #include #include #include #include #include #include #include #include #include using namespace std; const int MAXN = 10005;

NM的专栏 904

HDU 5381 The sum of gcd

The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description You have an array A,the length of A is n Let f(l,r)=∑ri=l∑rj=igcd

JYZ's Blog 478

hdu 5381 The sum of gcd

题意: 对于每次查询,计算∑i=lr∑j=irgcd(ai,ai+1,…,aj)\sum_{i=l}^{r}\sum_{j=i}^{r}gcd(a_i, a_{i+1}, \dots, a_j) 想法: 首先需要对于每一个ii预处理出[i,i→n][i, i \to n]这些区间的gcdgcd情况,即gcd(a[i]),gcd(a[i],a[i+],…,gcd(a[i],a[i+1

qqspeed 2391

(预处理+莫队算法)HDU - 5381 The sum of gcd

题意: 一个长度为n的数列,m次查询L到R之间所有连续子序列的gcd之和。 分析: 很明显的莫队算法。 很明显发现了gcd是单调递减的,并且最多存在32个的性质。 想了很久,脑补了许多种方法来拉伸L和R,但是都有漏洞。 实际上,这道题还是比较复杂的。。 在思考的过程中,我没有充分利用gcd的递减性质。 这题其实这题有共通之处,至少在我的做法上是这样的。 可以发现,在R向...

dijieluan7764的博客 249

【HDU5381_多校第八场B】【莫队算法】区间GCD之和_分段预处理

#include<stdio.h> #include<iostream> #include<string.h> #include<ctype.h> #include<math.h> #include<map> #include<set> #include<vector> #include<queue> #include<functional> #include<string> #include<al

snowy_smile的博客 941

HDU 5381 The sum of gcd 莫队算法

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5381 题意:给定一个数组,每次询问给出l和r,求出  思路:看的大牛的代码,心累 #include #include #include #include #include #include #define debug() puts("here") using namespace std;

弱智就要多努力 830
上一篇: 主席树(可持久化线段树)入门专题
下一篇: SPOJ COT2 树上的莫队算法,树上区间查询
HuanTongH
博客等级 码龄12年 7粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值