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 ...
随机推荐
- [转]浅谈 .NET Framework 与 .NET Core 的区别与联系
本文转自:http://www.cnblogs.com/huchaoheng/p/6295688.html 2017到了,咱们学点啥啊,要想知道学点啥,先弄清.NET Framework 与 .NET ...
- 【3】.net MVC 使用IPrincipal进行Form登录即权限验证
1.在MVC项目中添加用户类,可以根据实际项目需求添加必要属性 public class UserData { /// <summary> /// ID /// </summary& ...
- 4、springboot之全局异常捕获
1.新建一个springboot项目 添加一个全局异常的类 import org.springframework.web.bind.annotation.ControllerAdvice; impor ...
- svn 创建本地仓库
1. svnadmin create ~/repository 2. svnserve -d -r ~/repository 3. svn checkout file://~/repository $ ...
- RocketMQ读书笔记1——简述
[消息队列的功能介绍] 分布式消息队列可以提供应用解耦.流量削峰.消息分发.保证最终一致性.方便动态扩容等功能. [MQ使用场景1——应用解耦] 复杂的系统如电商系统,会存在多个子系统,如订单系统.库 ...
- IsWindow,findwindow
原文:http://www.cnblogs.com/ahuo/archive/2007/12/05/983354.html IsWindow 函数功能:该函数确定给定的窗口句柄是否识别一个已存在的窗口 ...
- Python类型总结
python 中处处是类的实例化 a=1 存储的是数字类型 而b='123'是字符串类型 []:读写方便的一张类型 True判断真假的一组{}键值对形式 class:则是描述静态元素和动态元素的结合体 ...
- Session、Cookie详解(2)
session是web开发里一个重要的概念,在大多数web应用里session都是被当做现成的东西,拿来就直接用,但是一些复杂的web应用里能拿来用的session已经满足不了实际的需求,当碰到这样的 ...
- 什么是git subcommand,如何创建git子命令?
大多数git用户知道如何在git中创建一个alias以便更便利地使用相关命令.很少有人知道至少不会好好利用的是:你实际上可以为Git创建扩展或者plugin,以便上git完成任何你希望完成的工作.这就 ...
- Hadoop HA集群的搭建
HA 集群搭建的难度主要在于配置文件的编写, 心细,心细,心细! ha模式下,secondary namenode节点不存在... 集群部署节点角色的规划(7节点)------------------ ...