HDU 4676 Sum Of Gcd 【莫队 + 欧拉】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=4676
Sum Of Gcd
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 908 Accepted Submission(s): 438
You need to answer some queries, each with the following format:
Give you two numbers L, R, you should calculate sum of gcd(a[i], a[j]) for every L <= i < j <= R.
Then follow T test cases.
For each test cases,the first line contains a number n(1<=n<= 20000).
The second line contains n number a1,a2,...,an.
The third line contains a number Q(1<=Q<=20000) denoting the number of queries.
Then Q lines follows,each lines contains two integer L,R(1<=L<=R<=n),denote a query.
Then for each query print the answer in one line.
题意概括:
给出 1~N 的一个排列,M次查询,每次查询 L ~ R 内 GCD( ai, aj ) [ L <= i < j <= R ] 的总和。
解题思路:
又是涉及 GCD 又是 涉及区间查询,头有点大。
首先莫队处理区间查询,其次欧拉函数解决GCD问题。
根据:

那么用 gcd( ai, aj) 代替上式的 n,我们可以得到:

问题就转换成了求 d 的欧拉函数,其实 d 是有很多重复的,那么我们只要统计出当前查询区间【L,R】内 d 出现的次数然后乘上其欧拉函数值,所求的的答案就是区间GCD的总和。
欧拉函数值和对原序列的每一项的因数分解预处理时搞定。
AC code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std; const int MAXN = 2e4+;
int unit, a[MAXN], N, M, cnt[MAXN];
LL ans[MAXN], phi[MAXN];
vector<int>factor[MAXN]; struct Query
{
int l, r, idx;
friend bool operator < (const Query & a, const Query & b){
int x1 = a.l/unit, x2 = b.l/unit;
if(x1 != x2) return x1 < x2;
return a.r < b.r;
}
}Q[MAXN]; void init()
{
for(int i = ; i < MAXN; i++){ //分解因子
for(int j = i; j < MAXN; j+=i)
factor[j].push_back(i);
} phi[] = ; //欧拉函数
for(int i = ; i < MAXN; i++){
phi[i] = i;
}
for(int i = ; i < MAXN; i++){
if(phi[i] == i){
for(int j = i; j < MAXN; j+=i)
phi[j] = phi[j]/i*(i-);
}
//puts("zjy");
}
} LL add(int x)
{
LL res = ;
for(auto d : factor[x]) res+=cnt[d]*phi[d];
for(auto d : factor[x]) cnt[d]++;
return res;
} LL del(int x)
{
LL res = ;
for(auto d : factor[x]) cnt[d]--;
for(auto d : factor[x]) res+=cnt[d]*phi[d];
return -res;
} void solve()
{
memset(cnt, , sizeof(cnt));
int L = , R = ;
LL cur = ;
for(int i = ; i <= M; i++){
while( L < Q[i].l) cur += del(a[L++]);
while( L > Q[i].l) cur += add(a[--L]);
while( R < Q[i].r) cur += add(a[++R]);
while( R > Q[i].r) cur += del(a[R--]);
ans[Q[i].idx] = cur;
//puts("zjy");
}
} int main()
{
int T_Case, Cas = ;
init();
//puts("zjy");
scanf("%d", &T_Case);
while(T_Case--){
scanf("%d", &N);
for(int i = ; i <= N; i++) scanf("%d", &a[i]);
scanf("%d", &M);
for(int i = ; i <= M; i++){
scanf("%d %d", &Q[i].l, &Q[i].r);
Q[i].idx = i;
}
unit = sqrt(N);
sort(Q+, Q++M);
solve();
printf("Case #%d:\n", ++Cas);
for(int i = ; i <= M; i++) printf("%lld\n", ans[i]);
}
return ;
}
HDU 4676 Sum Of Gcd 【莫队 + 欧拉】的更多相关文章
- hdu 4676 Sum Of Gcd 莫队+phi反演
Sum Of Gcd 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4676 Description Given you a sequence of ...
- hdu 4676 Sum Of Gcd 莫队+数论
题目链接 给n个数, m个询问, 每个询问给出[l, r], 问你对于任意i, j.gcd(a[i], a[j]) L <= i < j <= R的和. 假设两个数的公约数有b1, ...
- HDU-4676 Sum Of Gcd 莫队+欧拉函数
题意:给定一个11~nn的全排列AA,若干个询问,每次询问给出一个区间[l,r][l,r],要求得出∑l≤i<j≤r gcd(Ai,Aj)的值. 解法:这题似乎做的人不是很多,蒟蒻当然不会做只 ...
- 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 ...
- 【HDU4676】Sum Of Gcd(莫队+欧拉函数)
点此看题面 大致题意: 多组询问,求\(\sum_{i=L}^R\sum_{j=i+1}^Rgcd(i,j)\). 推式子 这道题我们可以考虑,每个因数\(d\)被统计答案的次数,肯定与其出现次数有关 ...
- hdu5381 The sum of gcd]莫队算法
题意:http://acm.hdu.edu.cn/showproblem.php?pid=5381 思路:这个题属于没有修改的区间查询问题,可以用莫队算法来做.首先预处理出每个点以它为起点向左和向右连 ...
- hdu 4676 Sum Of Gcd
离线+分块!! 思路:序列a[1],a[2],a[3]……a[n] num[i]表示区间[L,R]中是i的倍数的个数:euler[i]表示i的欧拉函数值. 则区间的GCD之和sum=∑(C(num[i ...
- Hdu5381-The sum of gcd(莫队)
题意我就不说了 解析: 莫队,先预处理出以i为右端点的区间的gcd值,有一些连续的区间的gcd值是相同的,比如[j,i],[j+1,i],[j+2,i]的gcd值是相同的,我们可以把[j,j+2] ...
- HDOJ 5381 The sum of gcd 莫队算法
大神题解: http://blog.csdn.net/u014800748/article/details/47680899 The sum of gcd Time Limit: 2000/1000 ...
随机推荐
- Java - 用builder代替构造器
静态工厂和够构造器有一个共同的局限性:遇到大量的参数时无法很好的扩展. 先说说构造器. 其实field不多时重叠构造器(telescoping constructor)是个不错的方法,易于编写也易于调 ...
- Backbone之温故而知新1-MVC
在忙碌了一段时间之后,又有了空余时间来学习新的东西,自从上次研究了backbone之后,一直不得入门,今天有时间有温故了一次,有了些许进步在此记录下, 在开始之前,不得不提一下我的朋友给了我“豆瓣音乐 ...
- react-native学习之入门app
1.项目初始化: react-native init MyProject 2.启动项目: cd MyProject react-native start 新开cmd窗口: react-native r ...
- Java基础(六)包装类
一.包装类 JAVA是一种面向对象语言,java中的类把方法与数据连接在一起,但在JAVA中不能定义基本类型对象,为了能将基本类型视为对象进行处理,java为每个基本类型都提供了包装类. 对应关系如下 ...
- shell脚本报错 value too great for base
此错误是shell脚本在计算以0开头的数字时,默认以8进制进行计算,导致在计算08时超过了8进制的范围,报此错误. shell脚本代码如下: #!/bin/bash a= ..} do a=$[$a+ ...
- CSS3弹性盒布局
使用自适应的窗口弹性盒布局 可以使div总宽度等于浏览器宽度,而且可以随着浏览器的改变而改变. <!DOCTYPE html> <html lang="zh-CN" ...
- mysql的一些sql用法
mysql中修改列名: alter table 表名 change abc def 列类型;比如 alter table student change pws psw char(10);
- Python爬虫教程-20-xml 简介
本篇简单介绍 xml 在python爬虫方面的使用,想要具体学习 xml 可以到 w3school 查看 xml 文档 xml 文档链接:http://www.w3school.com.cn/xmld ...
- 购物车动画(Android)
购物车动画(Android) 前言:当我们写商城类的项目的时候,一般都会有加入购物车的功能,加入购物车的时候会有一些抛物线动画,最近做到这个功能,借助别人的demo写了一个. 效果: 开发环境:And ...
- 函数arguments对象
一.arguments对象 arguments 是一个对应于传递给函数的参数的类数组对象. 二.语法 arguments 三.描述 arguments对象是所有(非箭头)函数中都可用的局部变量.你可以 ...