大神题解:

http://blog.csdn.net/u014800748/article/details/47680899

The sum of gcd

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 526    Accepted Submission(s): 226

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
 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector> using namespace std; const int maxn=10100;
typedef long long int LL; struct G
{
G(){}
G(int _id,LL _g):id(_id),g(_g){} int id;
LL g; void toString()
{
printf("id: %d g: %lld\n",id,g);
}
}; int n,a[maxn],Q;
vector<G> VL[maxn],VR[maxn];
struct Que
{
int L,R,id;
bool operator<(const Que& que) const
{
if(L!=que.L) return L<que.L;
return R<que.R;
}
}que[maxn]; void PreInit()
{
/// get Left Point
/// 以i为右端点,预处理出左边的段
for(int i=1;i<=n;i++)
{
VL[i].clear();
if(i==1)
{
VL[i].push_back(G(i,a[i]));
}
else
{
LL curg=a[i];int L=i;
for(auto &it : VL[i-1])
{
int g=__gcd(it.g,curg);
if(g!=curg) VL[i].push_back(G(L,curg));
curg=g; L=it.id;
}
VL[i].push_back(G(L,curg));
}
}
/// get Right Point
/// 以i为左端点,预处理出右边的段
for(int i=n;i>=1;i--)
{
VR[i].clear();
if(i==n)
{
VR[i].push_back(G(i,a[i]));
}
else
{
LL curg=a[i];int R=i;
for(auto &it : VR[i+1])
{
int g=__gcd(curg,it.g);
if(g!=curg) VR[i].push_back(G(R,curg));
curg=g; R=it.id;
}
VR[i].push_back(G(R,curg));
}
}
} /// 计算L,R之间的值
LL calu(int type,int L,int R)
{
LL ret=0;
if(type==0)
{
int tr=R;
for(auto &it : VL[R])
{
if(it.id>=L)
{
ret+=(tr-it.id+1)*it.g;
tr=it.id-1;
}
else
{
ret+=(tr-L+1)*it.g;
break;
}
}
}
else if(type==1)
{
int tr=L;
for(auto &it : VR[L])
{
if(it.id<=R)
{
ret+=(it.id-tr+1)*it.g;
tr=it.id+1;
}
else
{
ret+=(R-tr+1)*it.g;
break;
}
}
}
return ret;
} LL ans[maxn]; int main()
{
int T_T;
scanf("%d",&T_T);
while(T_T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
PreInit(); scanf("%d",&Q);
for(int i=0,l,r;i<Q;i++)
{
scanf("%d%d",&l,&r);
que[i].L=l; que[i].R=r; que[i].id=i;
}
sort(que,que+Q); int L=1,R=0; LL ret=0;
for(int i=0;i<Q;i++)
{
while(R<que[i].R)
{
R++;
ret+=calu(0,L,R);
}
while(R>que[i].R)
{
ret-=calu(0,L,R);
R--;
}
while(L<que[i].L)
{
ret-=calu(1,L,R);
L++;
}
while(L>que[i].L)
{
L--;
ret+=calu(1,L,R);
}
ans[que[i].id]=ret;
} for(int i=0;i<Q;i++)
cout<<ans[i]<<endl;
}
return 0;
}

HDOJ 5381 The sum of gcd 莫队算法的更多相关文章

  1. hdu5381 The sum of gcd]莫队算法

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=5381 思路:这个题属于没有修改的区间查询问题,可以用莫队算法来做.首先预处理出每个点以它为起点向左和向右连 ...

  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-4676 Sum Of Gcd 莫队+欧拉函数

    题意:给定一个11~nn的全排列AA,若干个询问,每次询问给出一个区间[l,r][l,r],要求得出∑l≤i<j≤r  gcd(Ai,Aj)的值. 解法:这题似乎做的人不是很多,蒟蒻当然不会做只 ...

  4. Hdu5381-The sum of gcd(莫队)

    题意我就不说了   解析: 莫队,先预处理出以i为右端点的区间的gcd值,有一些连续的区间的gcd值是相同的,比如[j,i],[j+1,i],[j+2,i]的gcd值是相同的,我们可以把[j,j+2] ...

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

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

  6. hdu 4676 Sum Of Gcd 莫队+数论

    题目链接 给n个数, m个询问, 每个询问给出[l, r], 问你对于任意i, j.gcd(a[i], a[j]) L <= i < j <= R的和. 假设两个数的公约数有b1, ...

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

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

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

    前言: 主要最近在刷莫队的题,这题GCD的特性让我对莫队的使用也有了新的想法.给福利:神犇的一套莫队算法题 先撇开题目,光说裸的一个莫队算法,主要的复杂度就是n*sqrt(n)对吧,这里我忽略了一个左 ...

  9. hdu 5381 The sum of gcd

    知道对于一个数列,如果以x为左(右)端点,往右走,则最多会有log(a[x])个不同的gcd,并且有递减性 所以会分成log段,每一段的gcd相同 那我们可以预处理出对于每一个位置,以这个位置为左端点 ...

随机推荐

  1. Spring Boot 打包分离依赖 JAR 和配置文件

    <properties> <java.version>1.8</java.version> <project.build.sourceEncoding> ...

  2. Python:webshell 跳板机审计服务器

    1.修改paramiko源码包实现 https://github.com/paramiko/paramiko/tree/1.10.1 下载源码包 unzip paramiko-1.10.1.zip p ...

  3. LINUX:Contos7.0 / 7.2 LAMP+R 下载安装Mysql篇

    文章来源:http://www.cnblogs.com/hello-tl/p/7569097.html 更新时间:2017-09-21 16:06 简介 LAMP+R指Linux+Apache+Mys ...

  4. GROUP函数

    GROUP_ID 首先我们看看官方的解释: 大意是GROUP_ID用于区分相同分组标准的分组统计结果. 解释起来比较抽象,下面我们来看看具体的案例. 例1:单一分组 SQL> select gr ...

  5. 多.h项目出现的问题:使用了预编译头依然出现error LNK2005:***obj已在***obj中定义与c++ error C2011: “xxx”:“class”类型重定义解决办法

    使用了预编译头依然出现error LNK2005:***obj已在***obj中定义 造成该问题的可能性比较多,本人将在今后遇到时添加进来,今天先放出本人遇到的一种情况. 多重包含含有变量定义的.h文 ...

  6. 当java web项目部署到服务器上时,无法将图片等媒体文件保存到服务器的最终奥义

    今天,我在部署web项目至云服务器上(Tomcat8.0)时,突然发现我的应用,无法上传图片,视频等多媒体文件了,一再检查自己的代码逻辑没有问题之后,逐一排查,首先想到的就是看一下控制台打印的日志,日 ...

  7. windows下mysql使用实录

    之前密码忘了,卸载重装,配置好环境变量,登录,成功 操作命令可参考http://www.runoob.com/mysql/mysql-tutorial.html 这里只列举了我需要用到的命令 登录:m ...

  8. Mybatis传递多个参数的4种方式(干货)

    Mybatis传递多个参数的4种方式(干货)-----https://blog.csdn.net/youanyyou/article/details/79406486

  9. 開啟活動監視器 (SQL Server Management Studio)

    本主題描述如何開啟 [活動監視器] 來取得有關 SQL Server 處理序以及這些處理序如何影響目前 SQL Server 執行個體的資訊. 此外,本主題也描述如何設定 [活動監視器] 的重新整理間 ...

  10. CentOS 7 & Chinese Fonts bug

    CentOS 7 & Chinese Fonts bug # check $ yum grouplist $ yum grouplist hidden # root $ yum groupin ...