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(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
题意:一句话题意;
思路:首先莫队离线处理,式必须的;
   然后重点就在于如何更新那个变化的值;
   根据取模的性质,每次取模最少/2;
   gcd也是同理;
   也就是说区间的gcd不同数的个数最多不超过log(n)个;
   这样就可以更新了;
   开始我写了一个RMQ,每次二分查找每一段,超时了;
   然后学到一个预处理的姿势;
   预处理见代码init那段;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
#define bug(x) cout<<"bug"<<x<<endl;
const int N=1e4+,M=4e6+,inf=;
const ll INF=1e18+,mod=1e9+; /// 数组大小 int a[N];
int n,pos[N],k;
vector<pair<int,int> >l[N],r[N];
struct is
{
int l,r,now;
bool operator <(const is &b)const
{
if(pos[l]!=pos[b.l])
return pos[l]<pos[b.l];
return r<b.r;
}
}p[N];
ll out[N],ans;
void prex(int L,int R,int flag)
{
ll sum=;
int p=L;
for(int i=;i<l[L].size();i++)
{
int k=min(R,l[L][i].first);
if(k>=p)
sum+=1LL*(k-p+)*l[L][i].second;
if(k>=R)break;
p=k+;
}
if(flag==)ans+=sum;
else ans-=sum;
} void nexx(int L,int R,int flag)
{
ll sum=;
int p=R;
for(int i=;i<r[R].size();i++)
{
int k=max(r[R][i].first,L);
if(p>=k)
sum+=1LL*(p-k+)*r[R][i].second;
if(k<=L)break;
p=k-;
}
if(flag==)ans+=sum;
else ans-=sum;
}
void init()
{
for(int i=;i<=n;i++)
l[i].clear(),r[i].clear();
ans=;
// 预处理l
l[n].push_back(make_pair(n,a[n]));
for(int i=n-;i>=;i--)
{
int g=a[i];
int p=i;
for(int j=;j<l[i+].size();j++)
{
int k=__gcd(g,l[i+][j].second);
if(g!=k)l[i].push_back(make_pair(p,g));
g=k;
p=l[i+][j].first;
}
l[i].push_back(make_pair(p,g));
}
//预处理r
r[].push_back(make_pair(,a[]));
for(int i=;i<=n;i++)
{
int g=a[i];
int p=i;
for(int j=;j<r[i-].size();j++)
{
int k=__gcd(g,r[i-][j].second);
if(g!=k)r[i].push_back(make_pair(p,g));
g=k;
p=r[i-][j].first;
}
r[i].push_back(make_pair(p,g));
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
k=sqrt(n);
for(int i=; i<=n; i++)
scanf("%d",&a[i]),pos[i]=(i-)/k+;
init();
int q;
scanf("%d",&q);
for(int i=; i<=q; i++)
scanf("%d%d",&p[i].l,&p[i].r),p[i].now=i;
sort(p+,p++q);
int L=,R=;
for(int i=; i<=q; i++)
{
while(L<p[i].l)
{
prex(L,R,);
L++;
}
while(L>p[i].l)
{
L--;
prex(L,R,);
}
while(R>p[i].r)
{
nexx(L,R,);
R--;
}
while(R<p[i].r)
{
R++;
nexx(L,R,);
}
out[p[i].now]=ans;
}
for(int i=; i<=q; i++)
printf("%lld\n",out[i]);
}
return ;
}
 

hdu 5381 The sum of gcd 莫队+预处理的更多相关文章

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

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

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

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

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

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

  4. 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 ...

  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. hdu5381 The sum of gcd]莫队算法

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

  8. HDU-4676 Sum Of Gcd 莫队+欧拉函数

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

  9. hdu 5381 The sum of gcd

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

随机推荐

  1. [vue]计算和侦听属性(computed&watch)

    先看一下计算属性 vue只有data区的数据才具备响应式的功能. 计算和侦听属性 - v-text里可以写一些逻辑 <div id="example"> {{ mess ...

  2. POJ2488:A Knight's Journey(dfs)

    http://poj.org/problem?id=2488 Description Background The knight is getting bored of seeing the same ...

  3. jquery closest & parent比较

    .closest() .parents() 从当前元素开始 从父元素开始 沿 DOM 树向上遍历,直到找到已应用选择器的一个匹配为止. 沿 DOM 树向上遍历,直到文档的根元素为止,将每个祖先元素添加 ...

  4. JavaScrip总体

    js: 简单对象: 数字 | 字符串 | 这三个像对象,有方法,但不可变 布尔值 | null undefined 对象:无类型,k-v对集合:函数.数组.REG.... JavaScript是一种l ...

  5. python开发中容易犯的错误整合

    写在前面 长期更新的博文.多数是一些比较隐蔽的问题.欢迎留言补充. pip并不是那么安逸 pip安装对于开发者来说确实是一种解放.可以自动安装依赖包,但执行最简单的pip安装命令时,并不是所有的依赖都 ...

  6. iOS 网易彩票-1框架搭建

    仿网易彩票,最终要做成的效果如下: 一.分层搭建 1.新建一个项目,Lottery.只支持7.1以上坚屏. 2.将素材全部图片全部拉到相应的文件夹里. 3.选中Lottery--右键Show in F ...

  7. 电子地图/卫星地图下载并转存为jpg图片

    1.下载水经注万能地图下载器破解版 http://download.csdn.net/download/hyb2012/8714725,此软件为绿色免安装且免注册 2.下载后解压缩后,运行sgwn.e ...

  8. label--input

    .form-group { margin-bottom: 15px; position: relative;}.control-label{ float: left; width: 15%; text ...

  9. PTA 团体程序设计天梯赛 L3-020 至多删三个字符

    $f[i][j]$表示到第$i$个字符,已经删去了$j$个字符的方案数. 显然的转移: $f[i][j] = f[i - 1][j] + f[i - 1][j - 1]$ 但是这样会有重复,我们考虑什 ...

  10. Java设计模式应用——组合模式

    组合模式实际上是一种树形数据结构.以windows目录系统举例,怎么样用java语言描述一个文件夹? 定义一个文件夹类,文件夹类中包含若干个子文件类和若干个文件类. 进一步抽象,把文件夹和文件都看做节 ...