题目链接: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. 八大排序算法之四选择排序—堆排序(Heap Sort)

    堆排序是一种树形选择排序,是对直接选择排序的有效改进. 基本思想: 堆的定义如下:具有n个元素的序列(k1,k2,...,kn),当且仅当满足 时称之为堆.由堆的定义可以看出,堆顶元素(即第一个元素) ...

  2. URL List

    wifi driver http://wenku.baidu.com/view/5fb275e9b8f67c1cfad6b85e.html http://wenku.baidu.com/view/a5 ...

  3. 【转】启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误的解决方法! .

    转载地址:http://blog.csdn.net/zyz511919766/article/details/7442633 原因1:给定目录下jvm.dll不存在. 对策:(1)重新安装jre或者j ...

  4. c#之委托所有方法

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

  5. Excel 函数

    Excel 函数: 一.定义: Excel 函数即是预先定义,执行计算.分析等处理数据任务的特殊公式. 二.结构: 1.单一结构 =函数名(参数1,参数2,参数3.....) 示例:=sum(A3:A ...

  6. Poj(1797) Dijkstra对松弛条件的变形

    题目链接:http://poj.org/problem?id=1797 题意:从路口1运货到路口n,最大的运货重量是多少?题目给出两路口间的最大载重. 思路:j加到s还是接到K下面,取两者的较大者,而 ...

  7. Application_Error异常处理

    /// <summary> /// 捕捉异常 /// </summary> protected void Application_Error() { // 获得前一个异常的实例 ...

  8. [Django_1_2]数据库设置

    Django 数据库设置 本篇将介绍Django中的数据库设置,了解模型(models,数据库中的表项设计). 上一篇文章为:<a href="http://www.cnblogs.c ...

  9. 2013年江西理工大学C语言程序设计竞赛(初级组)

    ACM ICPC WORLD FINAL 解法:排序大家都知道,去重的话,初学者用数组就好了 #include<algorithm> #include<iostream> us ...

  10. Android开发之获取本地视频和获取自拍视频

    1.获取本地所有视频 public void getLoadMedia() { Cursor cursor = UILApplication.instance.getApplicationContex ...