hdu 5381 The sum of gcd
知道对于一个数列,如果以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的更多相关文章
- hdu 5381 The sum of gcd(线段树+gcd)
题目链接:hdu 5381 The sum of gcd 将查询离线处理,依照r排序,然后从左向右处理每一个A[i],碰到查询时处理.用线段树维护.每一个节点表示从[l,i]中以l为起始的区间gcd总 ...
- 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 ...
- 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 ...
- 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 ...
- HDU 5381 The sum of gcd (技巧,莫队算法)
题意:有一个含n个元素的序列,接下来有q个询问区间,对每个询问区间输出其 f(L,R) 值. 思路: 天真单纯地以为是道超级水题,不管多少个询问,计算量顶多就是O(n2) ,就是暴力穷举每个区间,再直 ...
- 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 ...
- HDOJ 5381 The sum of gcd 莫队算法
大神题解: http://blog.csdn.net/u014800748/article/details/47680899 The sum of gcd Time Limit: 2000/1000 ...
- 【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= ...
- hdu 4676 Sum Of Gcd 莫队+phi反演
Sum Of Gcd 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4676 Description Given you a sequence of ...
随机推荐
- contextloaderlistener
http://blog.csdn.net/c5153000/article/details/6234207 作用:在启动Web容器时,自动装配Spring applicationContext.xml ...
- 编译安装php 5.5 缺少依赖包 及解决方案
必要时可以用 YUM 选择安装以下相关软件包: #yum install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel ...
- Jquery easyui-combobox 的一个BUG
通过easyui-combobox的loadData方法,easyui-combobox可以实现一个带字符搜索的下拉框,如下图: 但是这个下拉框中的字符串如果包含一些特殊字符的时候,就会出现BUG,通 ...
- css浮动(folat),清除浮动(clear)(另加两种清除浮动方式,总共三种清除浮动方式)
css浮动(float) float是css样式,用于设置标签的居左浮动和居右浮动,浮动后的元素不属于html文档流,需要用清除浮动把文档拽回到文档流中 浮动值: left:向左浮动 right:向右 ...
- 对已经发布订阅的sqlserver进行修改-添加新的表
1.以服务器名称连接数据库 2.找到复制-本地发布-对应的数据库发布订阅-右键属性-选择项目-选择新增的表(没有看到,注意取消右侧的仅显示列表已选择的项目) 3.然后重新初始化所有订阅 4.如果出现“ ...
- 一些iOS心得
ARC 1,arc是什么? automatic referece counting mrc mannualiOS5 之后出来的技术// 2,arc的原理是什么?// 在程序编译的时候,系统帮我 ...
- Jenkins+Jmeter+Ant 接口持续集成(转)
来源:https://testerhome.com/topics/5186 为什么要用Jmeter做接口测试 当选择这套方案的时候,很多人会问,为什么选择Jmeter做Case管理?为什么不自己写框架 ...
- JS中数据类型及原生对象简介
js是一种专门设计用来给网页增加交互性的编程语言,它的技术体系包含了一下几个方面: 1.JavaScript核心语言定义:包括数据类型,变量,常量,运算符,语句等. 2.原生对象和内置对象 3.浏览器 ...
- Android Studio实现页面跳转(新页面或者网站)
一,跳转到另一个页面 百度了好久,好像好多种方法,从中挑选了一中比较方便的一中方法 利用Intent类进行实现 1,首先在firstActivity中添加相应的跳转命令代码 例如一下示例代码 if ( ...
- oracle 解锁表
//查询锁表id select session_id from v$locked_object; //查询该ID的serial# SELECT sid, serial#, username, osus ...