【题目】

The sum of gcd

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
 
 
【题意】

You have an array A,the length of A is n
Let f(l,r)=∑r i=l ∑r j=i gcd(ai,ai+1....aj) (n,m<=1000,ai<=1000000000)

 
【分析】
  HHHHHH我又没有想出来【嘲笑一下自己
  跟之前比赛那题的解法简直一模一样!!!
  可以离线做,然后扫描右端点,左端点存一个f[l]表示gcd(al)+gcd(al,al+1)+gcd(al,al+1,al+2)+...gcd(al,al+1,al+2,...ar) 【r为当前扫描到的右端点
  然后,如果新加入一个r,每一位的数都要加上gcd(a[l]+a[l+1]+…+a[r]),这最多只有logn段,因为左边的必然是右边的因数,(然后因数至少除以2吧)
  用链表弄这个,然后线段树或者树状数组维护区间和(树状数组的话要区间修改区间查询)
   O(nlognlogn)
  一生气全部LL 就能AC了ORZ。。
 
 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define Maxn 10010
#define LL long long LL a[Maxn]; struct hp
{
LL l,r,id;
LL ans;
}q[Maxn]; bool cmp(hp x,hp y) {return x.r<y.r;}
bool cmp2(hp x,hp y) {return x.id<y.id;} LL lt[Maxn],g[Maxn],last;
LL n,m; LL gcd(LL a,LL b)
{
if(b==) return a;
return gcd(b,a%b);
} LL c1[Maxn],c2[Maxn];
void add(LL l,LL r,LL y)
{
// printf("add %d %d %d\n",l,r,y);
for(LL i=l;i<=n;i+=i&(-i))
c1[i]+=y,c2[i]+=l*y;
r++;
for(LL i=r;i<=n;i+=i&(-i))
c1[i]-=y,c2[i]-=r*y;
} LL query(LL l,LL r)
{
// printf("ask %d %d ",l,r);
LL ans=;
for(LL i=r;i>=;i-=i&(-i))
ans+=c1[i]*(r+)-c2[i];
l--;
for(LL i=l;i>=;i-=i&(-i))
ans-=c1[i]*(l+)-c2[i];
// printf("%d\n",ans);
return ans;
} void ffind(LL r)
{
if(r==)
{
add(r,r,a[r]);
last=;lt[r]=;g[r]=a[r];
return;
}
lt[r]=last,last=r,g[r]=a[r];
for(LL i=last;lt[i];)
{
g[lt[i]]=gcd(g[lt[i]],a[r]);
if(g[lt[i]]==g[i])
{
lt[i]=lt[lt[i]];
}
else i=lt[i];
}
for(LL i=last;i;i=lt[i])
{
add(lt[i]+,i,g[i]);
}
} int main()
{
LL T;
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&n);
for(LL i=;i<=n;i++) scanf("%lld",&a[i]);
scanf("%lld",&m);
for(LL i=;i<=m;i++)
{
scanf("%lld%lld",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+,q++m,cmp);
memset(c1,,sizeof(c1));
memset(c2,,sizeof(c2));
LL now=;
for(LL i=;i<=m;i++)
{
while(now<q[i].r)
{
now++;
ffind(now);
}
q[i].ans=query(q[i].l,q[i].r);
}
sort(q+,q++m,cmp2);
for(LL i=;i<=m;i++) printf("%lld\n",q[i].ans);
}
return ;
}

2016-11-10 21:52:36


伟大的子区间离线做法,log段!!!!!

好多东东都是log段的说。。。

啊啊啊,我觉得我智障!!

想了好久子区间求和怎么破。。。

就记录一个lsm,rsm,满足结合律啊。。。。。

异或和sm的也是可以的!!!

每天智障24小时。。

【HDU 5381】 The sum of gcd (子区间的xx和,离线)的更多相关文章

  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

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

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

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

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

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

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

  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. [RAC] oracle rac 后台进程

    一.RAC后台进程 LMON:LOCK Monitor Processes 也被称为Global enqueue service monitor 监控整个集群状况,维护GCS的内存结构 监控非正常终止 ...

  2. Spring MVC自定义统一异常处理类,并且在控制台中输出错误日志

    在使用SimpleMappingExceptionResolver实现统一异常处理后(参考Spring MVC的异常统一处理方法), 发现出现异常时,log4j无法在控制台输出错误日志.因此需要自定义 ...

  3. centos6 install mplayer(multimedia)

    step_1 http://wiki.centos.org/AdditionalResources/Repositories/RPMForge step_2 http://wiki.centos.or ...

  4. Verilog-1995 VS Verilog-2001

    http://www.cnblogs.com/tshell/p/3236476.html 2001年3月IEEE正式批准了Verilog‐2001标准(IEEE1364‐2001),与Verilog‐ ...

  5. LSJ_NHibernate第一章 NHibernate介绍

    前言: 说起NHibernate网上资料真不少,但用的人却并不多,说起java的SSH框架大家可能就知道了,这里的H指的就是Hibernate,一款好用的ORM框架,在.net重写了这款好用的框架,名 ...

  6. NHibernate中的IQueryable和IQueryover

    今天在做一个小项目时,用到了NHibernate,使用了模糊查询(Like),在后台用IQueryable去接收Session.Query<T>()的查询结果. 代码如下: /// < ...

  7. php有三种工作模式

    php有三种工作模式. 其中是最常见的是php作为一个模块工作在一个多进程的webserver中, 例如apache webserver. apache会启动一个主进程, 多个子进程(php). 主进 ...

  8. JavaScript学习笔记 -- ES6学习(三) 变量的解构赋值

    1.解构赋值的定义 在ES6中,允许按照一定模式,从数组和对象中提取值(所谓解构),然后对变量进行赋值. var a = 1; var b = 2; var c = 3; //等价于 var [a, ...

  9. myeclipse启动报JVM terminated. Exit code=1

    报错信息如图: 解决办法: 删除当前workspaces下文件夹,路径为:%Workspaces%/.metadata/.plugins/org.eclipse.core.runtime

  10. What is the Xcopy Command?:

    Quote from: http://pcsupport.about.com/od/commandlinereference/p/xcopy-command.htm The xcopy command ...