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 ...
随机推荐
- js惊奇效果分享,和排序算法
分享地址:http://www.cnblogs.com/lhb25/p/8-amazing-codepen-demos.html 排序算法分享地址:http://www.w3cplus.com/js/ ...
- SQL 工具系列一
1.误删除数据恢复篇 ApexSQL Recover 可以恢复Delete Truncate drop,恢复 二进制大型对象 测试版本 每10行才会恢复 评估版本下载地址:只能用14天 所以基 ...
- java 的数据库操作--JDBC
一.java与数据库的交互 1.jdbc:java data base connectivity,java数据库连接.java的JDBC操作主要通过操作两个类进行连接操作:Connection 和 S ...
- Java温故而知新(1)集合类
Java中的集合类有以下所属关系:Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashMap└Wea ...
- Django 中间件实现用户认证与IP频率限制
1.URL访问过滤 通过装饰器进行用户认证非常方便,但是在添加部分需要认证的功能时,就需要再次添加装饰器,如果通过中间件来实现,就不需要再进行添加的操作. import re LOGIN_URL = ...
- NodeJS require路径
项目需要用nodejs,感觉nodejs是前端装逼神器了,是通向全栈工程师的必经之路哇,接下来开始踏上学习nodejs的征程.下面是第一个hello,world的程序. 1.server.js文件,这 ...
- USG防火墙基础
http://support.huawei.com/huaweiconnect/enterprise/thread-331003.html 华为防火墙产品线 安全区域 1. 默认防火墙区域 T ...
- FeatureLayer 里属性数据的提取与显示
我们用工程文件所发布的WebServer下,包含一个个图层,这些图层根据顺序进行了 0 开始的编号,这些就是FeatureLayer的地址了! FeatureLayer 包含了地图的属性信息,十分好用 ...
- 项目经验:GIS<MapWinGIS>建模第六天
针对管网的暴管发生情况的,关阀分析,能够更快,更及时给施工作人员找到最近需要关停的阀门点,及受影响的管网段,如在这个区域内,还能找到受影响需要停水的用户
- 替换空格(C++和Python 实现)
(说明:本博客中的题目.题目详细说明及参考代码均摘自 “何海涛<剑指Offer:名企面试官精讲典型编程题>2012年”) 题目 请实现一个函数,把字符串中的每个空格替换为 "%2 ...