题目链接:hdu 5317

  这题看数据量就知道需要先预处理,然后对每个询问都需要在 O(logn) 以下的复杂度求出,由数学规律可以推出 1 <= F(x) <= 7,所以对每组(L, R),只需要求出它们在 1~7 的范围内的数量,然后暴力求出 gcd 即可。因为符合递增,可以设一个结点 struct { v[8]; } 记录 1~7 的数量,结点间可以相加减,也就可以用前缀和的思想去做(其实我也是看了别人的题解才明白这种思想,一开始用二分不是超时就是 wa 了,不过我竟发现自己手写的二分比库函数 lower_bound 要快!而且至少快 7~8 倍以上!看来以后用二分都尽量自己手写好了 (ㄒoㄒ)~~ )

  先附上用前缀和的思想的代码,加入了输入输出挂:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ; struct node {
int v[];
node() { memset(v,,sizeof(v)); }
node operator + (const node &n2) const {
node add;
for(int i = ; i <= ; ++i)
add.v[i] = v[i] + n2.v[i];
return add;
}
node operator - (const node &n2) const {
node sub;
for(int i = ; i <= ; ++i)
sub.v[i] = v[i] - n2.v[i];
return sub;
}
node& operator += (const node &n2) {
*this = *this + n2;
return *this;
}
node& operator -= (const node &n2) {
return *this = *this - n2;
}
}; int num[N];
node _count[N];
inline void init(int n = N - ) {
for(int i = ; i <= n; ++i)
if(!num[i])
for(int j = i; j <= n; j += i) ++num[j];
for(int i = ; i <= n; ++i) {
node tmp;
++tmp.v[num[i]];
_count[i] = _count[i - ] + tmp;
}
} inline int gcd(int a, int b) {
return b == ? a: gcd(b, a % b);
} #include<cctype>
template <typename T>
inline void read(T &x) {
x = ;
char ch = getchar();
bool flag = ;
while(!isdigit(ch) && ch != '-') ch = getchar();
if(ch == '-') {
flag = ;
ch = getchar();
}
while(isdigit(ch)) {
x = x * + (ch - '');
ch = getchar();
}
if(flag) x = -x;
} template <typename T>
inline void write(const T &x) {
if(x < ) putchar(char(x + ''));
else write(x / );
} int main() {
int t,L,R;
init();
read(t);
while(t--) {
read(L); read(R);
node p = _count[R] - _count[L - ];
int ans = ;
for(int i = ; i <= ; ++i) {
if(!p.v[i]) continue;
--p.v[i];
for(int j = i; j <= ; ++j)
if(p.v[j]) ans = max(ans, gcd(i,j));
++p.v[i];
}
write(ans);
puts("");
}
return ;
}

  说到前缀和,就可以联想起高效动态维护前缀和的树状数组。没错,只要能求前缀和的数据结构,都能用树状数组去维护,它的适用范围不只是简单的 int,long long 或者 一维数组(二维树状数组去维护)等等。因此我定义成模板类:

 #include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
const int N = ; struct node {
int v[];
void clear() { memset(v,,sizeof(v)); }
node() { clear(); }
node operator + (const node &n2) const {
node add;
for(int i = ; i <= ; ++i)
add.v[i] = v[i] + n2.v[i];
return add;
}
node operator - (const node &n2) const {
node sub;
for(int i = ; i <= ; ++i)
sub.v[i] = v[i] - n2.v[i];
return sub;
}
}; #define lowbit(x) ((x)&-(x))
template <typename T>
struct tree {
T c[N];
int maxn;
void clear() { // 或者直接 memset(c, 0, sizeof(c)) 也可以;
for(int i = ; i <= maxn; ++i)
c[i].clear();
}
tree(int maxn = N - ): maxn(maxn) { clear(); }
T sum(int x) const {
T res;
while(x) {
res = res + c[x];
x -= lowbit(x);
}
return res;
}
void add(int x, T d) {
while(x <= maxn) {
c[x] = c[x] + d;
x += lowbit(x);
}
}
}; tree<node> tr; int num[N];
void init(int n = N - ) {
for(int i = ; i <= n; ++i)
if(!num[i])
for(int j = i; j <= n; j += i) ++num[j];
for(int i = ; i <= n; ++i) {
node tmp;
++tmp.v[num[i]];
tr.add(i, tmp);
}
} inline int gcd(int a, int b) {
return b == ? a: gcd(b, a % b);
} int main() {
int t,L,R;
init();
scanf("%d",&t);
while(t--) {
scanf("%d %d",&L,&R);
node p = tr.sum(R) - tr.sum(L - );
int ans = ;
for(int i = ; i <= ; ++i) {
if(!p.v[i]) continue;
--p.v[i];
for(int j = i; j <= ; ++j)
if(p.v[j]) ans = max(ans, gcd(i, j));
++p.v[i];
}
printf("%d\n",ans);
}
return ;
}

hdu 5317 RGCDQ(前缀和)的更多相关文章

  1. hdu 5317 RGCDQ (2015多校第三场第2题)素数打表+前缀和相减求后缀(DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5317 题意:F(x) 表示x的不同质因子的个数结果是求L,R区间中最大的gcd( F(i) , F(j ...

  2. HDU 5317 RGCDQ(素数个数 多校2015啊)

    题目链接:pid=5317" target="_blank">http://acm.hdu.edu.cn/showproblem.php?pid=5317 Prob ...

  3. ACM学习历程—HDU 5317 RGCDQ (数论)

    Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more an ...

  4. HDU 5317 RGCDQ (数论素筛)

    RGCDQ Time Limit: 3000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status ...

  5. 2015 Multi-University Training Contest 3 hdu 5317 RGCDQ

    RGCDQ Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  6. HDU 5317 RGCDQ (质数筛法,序列)

    题意:从1~1000,000的每个自然数质因子分解,不同因子的个数作为其f 值,比如12=2*2*3,则f(12)=2.将100万个数转成他们的f值后变成新的序列seq.接下来T个例子,每个例子一个询 ...

  7. HDU 5317 RGCDQ

    题意:f(i)表示i的质因子个数,给l和r,问在这一区间内f(i)之间任意两个数最大的最大公倍数是多少. 解法:先用筛法筛素数,在这个过程中计算f(i),因为f(i)不会超过7,所以用一个二维数组统计 ...

  8. 2015 HDU 多校联赛 5317 RGCDQ 筛法求解

    2015 HDU 多校联赛 5317 RGCDQ 筛法求解 题目  http://acm.hdu.edu.cn/showproblem.php? pid=5317 本题的数据量非常大,測试样例多.数据 ...

  9. hdu 5317 合数分解+预处理

    RGCDQ Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

随机推荐

  1. htmlnav

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 20150608_Andriod 发布问题处理

    参考地址: http://blog.csdn.net/cxc19890214/article/details/39120415 问题:当我们开发完成一个Android应用程序后,在发布该应用程序之前必 ...

  3. 实现LUT

    //实现LUT 查找表 #include "stdafx.h" #include <iostream> #include <opencv2/opencv.hpp& ...

  4. 基于SURF特征的图像与视频拼接技术的研究和实现(一)

    基于SURF特征的图像与视频拼接技术的研究和实现(一)      一直有计划研究实时图像拼接,但是直到最近拜读西电2013年张亚娟的<基于SURF特征的图像与视频拼接技术的研究和实现>,条 ...

  5. python递归小疑惑

    代码如下: def crawlAndGet(keyword, n): if n>0: jsondata = os.system('scrapy crawl beijing -a store_di ...

  6. Android开发之获取相册照片和获取拍照照片

    在Android的开发过程中,我们可能会读取手机里面的照片或者通过相机拍摄获取照片,这是两种常用的获取图片的方式,在做项目过程中也会经常遇到,下面来介绍一下这两种获取方式.. 1.从本地相册获取照片: ...

  7. EasyUI 自定义DataGrid分页

    DataGrid内建分页能力是强大的,它比自定义相对容易.在这个教程,我们将要创建DataGrid并且在页面工具栏中添加一些自定义按钮.标记<table id="tt"> ...

  8. linq的创建 和 数据的增删改查

    1.linq创建之前,一定要在sql做好数据表的主外键关系. 2.linq文件是以.dbml结尾,一般一个数据库的名字就是一个linq的名字 3,以实例来演示增删改查 数据库的名字为linq,里面有两 ...

  9. 方法参数out

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace _050505 ...

  10. Linux各发行版本简介

    简介 Linux 主要作为Linux发行版(通常被称为"distro")的一部分而使用.这些发行版由个人,松散组织的团队,以及商业机构和志愿者组织编写.它们通常包括了其他的系统软件 ...