知道对于一个数列,如果以x为左(右)端点,往右走,则最多会有log(a[x])个不同的gcd,并且有递减性

所以会分成log段,每一段的gcd相同

那我们可以预处理出对于每一个位置,以这个位置为左端点和右端点的时候,分别产生的gcd的值和分界处

那么这道题就可以用莫队算法了,O(n * sqrt(n) * logn)

标程是用线段树

代码:

  //File Name: hdu5381.cpp
//Author: long
//Mail: 736726758@qq.com
//Created Time: 2016年10月24日 星期一 11时36分49秒 #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <vector>
#include <set>
#include <map>
#include <stdlib.h>
#define LL long long
#define pii pair<int,int>
#define fir first
#define sec second
#define mp make_pair
using namespace std;
const int MAXN = + ;
int bel[MAXN],a[MAXN],cur_l,cur_r,tot;
LL ans[MAXN],cur_ans;
vector<pii> tol[MAXN],tor[MAXN];
struct Query{
int l,r,t;
bool operator < (const Query & x) const{
if(bel[l] == bel[x.l]) return r < x.r;
return bel[l] < bel[x.l];
}
}que[MAXN];
int gcd(int x,int y){
return y == ? x : gcd(y, x % y);
}
void init(int n){
pii now;
for(int i=;i<=n;i++){
tol[i].clear();
tol[i].push_back(mp(i,a[i]));
if(i == ) continue;
int tot = ,len = tol[i-].size();
for(int j=;j<len;j++){
now = tol[i-][j];
int d = gcd(now.sec,a[i]);
if(d == tol[i][tot].sec)
tol[i][tot].fir = now.fir;
else{
tol[i].push_back(mp(now.fir,d));
tot++;
}
}
}
for(int i=n;i>;i--){
tor[i].clear();
tor[i].push_back(mp(i,a[i]));
if(i == n) continue;
int tot = ,len = tor[i+].size();
for(int j=;j<len;j++){
now = tor[i+][j];
int d = gcd(a[i],now.sec);
if(d == tor[i][tot].sec)
tor[i][tot].fir = now.fir;
else{
tor[i].push_back(mp(now.fir,d));
tot++;
}
}
}
}
LL gettol(int l,int r){
LL res = ;
int pre = r,len = tol[r].size();
for(int i=;i<len;i++){
pii now = tol[r][i];
if(l < now.fir){
res += (LL)(pre - now.fir + ) * now.sec;
pre = now.fir - ;
}
else{
res += (LL)(pre - l + ) * now.sec;
break;
}
}
return res;
}
LL gettor(int l,int r){
LL res = ;
int pre = l,len = tor[l].size();
for(int i=;i<len;i++){
pii now = tor[l][i];
if(r > now.fir){
res += (LL)(now.fir - pre + ) * now.sec;
pre = now.fir + ;
}
else{
res += (LL)(r - pre + ) * now.sec;
break;
}
}
return res;
}
void mover(int to){
while(cur_r < to){
cur_r++;
cur_ans += gettol(cur_l,cur_r);
}
while(cur_r > to){
cur_ans -= gettol(cur_l,cur_r);
cur_r--;
}
}
void movel(int to){
while(cur_l < to){
cur_ans -= gettor(cur_l,cur_r);
cur_l++;
}
while(cur_l > to){
cur_l--;
cur_ans += gettor(cur_l,cur_r);
}
}
void solve(int n,int q){
init(n);
int block = (int)sqrt(n + 0.5);
for(int i=;i<=n;i++)
bel[i] = (n - ) / block + ;
sort(que+,que+q+);
cur_l = cur_r = ,cur_ans = a[];
for(int i=;i<=q;i++){
mover(que[i].r);
movel(que[i].l);
ans[que[i].t] = cur_ans;
}
for(int i=;i<=q;i++)
printf("%I64d\n",ans[i]);
}
int main(){
int t,n,q;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",a + i);
scanf("%d",&q);
for(int i=;i<=q;i++){
scanf("%d %d",&que[i].l,&que[i].r);
que[i].t = i;
}
solve(n,q);
}
return ;
}

hdu 5381 The sum of gcd的更多相关文章

  1. hdu 5381 The sum of gcd(线段树+gcd)

    题目链接:hdu 5381 The sum of gcd 将查询离线处理,依照r排序,然后从左向右处理每一个A[i],碰到查询时处理.用线段树维护.每一个节点表示从[l,i]中以l为起始的区间gcd总 ...

  2. hdu 5381 The sum of gcd 莫队+预处理

    The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) P ...

  3. hdu 5381 The sum of gcd 2015多校联合训练赛#8莫队算法

    The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) T ...

  4. 2015 Multi-University Training Contest 8 hdu 5381 The sum of gcd

    The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. HDU 5381 The sum of gcd (技巧,莫队算法)

    题意:有一个含n个元素的序列,接下来有q个询问区间,对每个询问区间输出其 f(L,R) 值. 思路: 天真单纯地以为是道超级水题,不管多少个询问,计算量顶多就是O(n2) ,就是暴力穷举每个区间,再直 ...

  6. HDU - 4676 :Sum Of Gcd (莫队&区间gcd公式)

    Given you a sequence of number a 1, a 2, ..., a n, which is a permutation of 1...n. You need to answ ...

  7. HDOJ 5381 The sum of gcd 莫队算法

    大神题解: http://blog.csdn.net/u014800748/article/details/47680899 The sum of gcd Time Limit: 2000/1000 ...

  8. 【HDU 5381】 The sum of gcd (子区间的xx和,离线)

    [题目] The sum of gcd Problem Description You have an array A,the length of A is nLet f(l,r)=∑ri=l∑rj= ...

  9. hdu 4676 Sum Of Gcd 莫队+phi反演

    Sum Of Gcd 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4676 Description Given you a sequence of ...

随机推荐

  1. CentOS7下安装MYSQL5.7

    第一种方式:yum安装 1.下载mysql57-community-release-el7-9.noarch 下载地址:http://dev.mysql.com/downloads/repo/yum/

  2. CodeForces #369 div2 D Directed Roads DFS

    题目链接:D Directed Roads 题意:给出n个点和n条边,n条边一定都是从1~n点出发的有向边.这个图被认为是有环的,现在问你有多少个边的set,满足对这个set里的所有边恰好反转一次(方 ...

  3. Oracle创建,删除用户与表空间

    1.创建表空间与用户 a:创建数据表空间 create tablespace user_data logging datafile 'D:\oracle\product\10.2.0\oradata\ ...

  4. SQL Server基本函数

    1. 字符串函数 1.1 datalength( char_expr ) ,返回表达式的字节数,不包含尾随空格 返回类型:如果 expression 的数据类型为 varchar(max).nvarc ...

  5. The Layout Process on Mac OSX and iOS

    First we will recap the steps it takes to bring views on screen with Auto Layout enabled. When you’r ...

  6. OSI模型

    1.物理层 •设备间接收或发送比特流 •说明电压.线速和线缆等 例子: EIA/TIA-232 V.35 2. 数据链路层 •将比特组合成字节进而组合成帧 •用MAC地址访问介质 •错误发现但不能纠正 ...

  7. ACE - Reactor模式源码剖析及具体实现(大量源码慎入)

    原文出自http://www.cnblogs.com/binchen-china,禁止转载. 在之前的文章中提到过Reactor模式和Preactor模式,现在利用ACE的Reactor来实现一个基于 ...

  8. UWP/Win10新特性系列—UserConsentVerifier

    在UWP开发中,微软提供了新的用户许可验证方式-指纹(生物识别).Pin.密码验证.在爆料的新型Win10 Mobile移动设备中,会增加虹膜识别等先进的用户身份识别技术,微软现在统一了身份验证的AP ...

  9. leetcode52. N-Queens II

    Follow up for N-Queens problem. Now, instead outputting board configurations, return the total numbe ...

  10. Python::OS 模块 -- 文件和目录操作

    os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...