题目链接

给n个数, m个询问, 每个询问给出[l, r], 问你对于任意i, j。gcd(a[i], a[j]) L <= i < j <= R的和。

假设两个数的公约数有b1, b2, b2...bn, 那么这两个数的最大公约数就是phi[b1] + phi[b2] + phi[b3]...+phi[bn]。

知道这个就可以用莫队了, 具体看代码。

#include <bits/stdc++.h>

using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = ;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 2e4+;
vector <int> v[maxn];
struct node
{
int l, r, block, id;
}q[maxn];
bool cmp(const node& a, const node& b)
{
if(a.block == b.block)
return a.r < b.r;
return a.block < b.block;
}
int phi[maxn], cnt[maxn], a[maxn];
ll res, ans[maxn];
void add(int x)
{
for(int i = ; i < v[x].size(); i++) {
res += phi[v[x][i]]*(cnt[v[x][i]]++);
}
}
void sub(int x)
{
for(int i = ; i < v[x].size(); i++) {
res -= phi[v[x][i]]*(--cnt[v[x][i]]);
}
}
void solve(int m)
{
int L = , R = ;
res = ;
mem(cnt);
for(int i = ; i < m; i++) {
while(R < q[i].r) {
add(a[++R]);
}
while(R > q[i].r) {
sub(a[R--]);
}
while(L < q[i].l) {
sub(a[L++]);
}
while(L > q[i].l) {
add(a[--L]);
}
ans[q[i].id] = res;
}
}
void init()
{
for(int i = ; i < maxn; i++) {
phi[i] = i;
for(int j = i; j < maxn; j += i) {
v[j].pb(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-);
}
}
}
}
int main()
{
init();
int t, n, m;
cin>>t;
for(int casee = ; casee <= t; casee++) {
scanf("%d", &n);
int BLOCK = sqrt(n*1.0);
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].block = q[i].l/BLOCK;
q[i].id = i;
}
sort(q, q+m, cmp);
solve(m);
printf("Case #%d:\n", casee);
for(int i = ; i < m; i++) {
printf("%lld\n", ans[i]);
}
}
}

hdu 4676 Sum Of Gcd 莫队+数论的更多相关文章

  1. hdu 4676 Sum Of Gcd 莫队+phi反演

    Sum Of Gcd 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4676 Description Given you a sequence of ...

  2. HDU 4676 Sum Of Gcd 【莫队 + 欧拉】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=4676 Sum Of Gcd Time Limit: 10000/5000 MS (Java/Others ...

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

  4. HDU-4676 Sum Of Gcd 莫队+欧拉函数

    题意:给定一个11~nn的全排列AA,若干个询问,每次询问给出一个区间[l,r][l,r],要求得出∑l≤i<j≤r  gcd(Ai,Aj)的值. 解法:这题似乎做的人不是很多,蒟蒻当然不会做只 ...

  5. hdu5381 The sum of gcd]莫队算法

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=5381 思路:这个题属于没有修改的区间查询问题,可以用莫队算法来做.首先预处理出每个点以它为起点向左和向右连 ...

  6. Hdu5381-The sum of gcd(莫队)

    题意我就不说了   解析: 莫队,先预处理出以i为右端点的区间的gcd值,有一些连续的区间的gcd值是相同的,比如[j,i],[j+1,i],[j+2,i]的gcd值是相同的,我们可以把[j,j+2] ...

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

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

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

  9. HDU 4358 Boring counting(莫队+DFS序+离散化)

    Boring counting Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others) ...

随机推荐

  1. zoj1107 FatMouse and Cheese

    这是一道记忆化搜索,也就是有记录的搜索. 注意点:一次走k步不能拐弯 int bfs(int x,int y) { ; ) return ans[x][y]; ;i<;i++) { ;j< ...

  2. size对齐

    写了很多程序,在很多地方都要用到内存长度对齐,比如文件的大小,pe文件内存的对齐等等. 下面记下两种简单的方法,觉得没啥大用处. #include <IOSTREAM> #include ...

  3. c++11: <thread>学习

    <thread>头文件中包含thread类与this_thread命名空间,下面逐一介绍. thread类 1. 构造函数 (1)默认构造函数 thread() noexcept; 默认构 ...

  4. python基础:映射和集合类型

    python字典的迭代器遍历 字典有一个方法可以返回该字典的迭代器,这个方法就是: dict. iteritems() 当在字典中增加或者删除字典entry的时候,迭代器会失效的,类似于C++的stl ...

  5. 浏览器文档播放Shockwave Flash 插件问题

    浏览器被提示shockwave flash crashed怎么办?在使用浏览器的时候经常被提示shockwave flash crashed,flash插件崩溃,网页就会出现一些无法显示的文件,下面绿 ...

  6. JavaScript总结之鼠标划过弹出div单击出现对话框

    为了满足他们的永无止境的要求,我可谓是任劳任怨啊,累断了双手,看瞎了双眼.这个是来写鼠标划过一个按钮,然后弹出一个小提示框解释,另外根据radio是否选中,判断点击后如何执行,然后执行之后再有一个确认 ...

  7. js/jquery获取当前页面URL地址并判断URL字符串中是否包含某个具体值

    js/jquery获取当前页面URL地址并判断URL字符串中是否包含某个具体值本文介绍jquery/js获取当前页面url地址的方法,在jquery与js中获取当前页面url方法是一样的,因为jque ...

  8. Python命令行参数sys.argv[]

    学习C语言的时候就没弄明白命令行参数的用法,在学习Pyton 的时候又遇到了命令行参数,在这里稍微学习了一下,稍微明白了一些在这里做个记录方便后面回顾复习. Sys.argv[]是用来获取命令行参数的 ...

  9. sshd被攻击的自动防御方法v2

      1.增加了“频繁攻击的封锁时间”,即设置为上次攻击时间的2倍 2.加入了数据库支持,将攻击者相关信息记录入库,如攻击者ip.攻击次数.封锁时间 3.简化了代码   具体实现步骤如下:   1.创建 ...

  10. linux配置jdk环境详解

    环境:Redhat Server 5.1(虚拟机) 工具:Xftp4  jdk-7-linux-i586.rpm文件 步骤1:把jdk-7-linux-i586.rpm文件拷贝到/usr/local目 ...