题目链接: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. Spring MVC 中请求返回之后的页面没法加载css、js等静态文件

    1.是否被拦截,这个在Web.xml配置中servlet拦截是“/”,如果是则 a.使用spring MVC 的静态资源文件 <!-- 静态文件访问,主要是针对DispatcherServlet ...

  2. 【转】去掉eclipse的validate

    转载地址:http://www.blogjava.net/leisure/archive/2013/01/11/394087.html 困扰了好几天,与大家共享 1,在project名称上右键选择pr ...

  3. htmlnav

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

  4. 欧拉回路-Door Man 分类: 图论 POJ 2015-08-06 10:07 4人阅读 评论(0) 收藏

    Door Man Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2476 Accepted: 1001 Description ...

  5. thinkphp 实现无限极分类

    thinkphp实现无限极分类,获得所有的子类 今天学习测试了一上午也没有整出来,一开始一直没有办法把所有的子分类拿出来. 最后找到原因: 每次调用的时候没有在最后return的位置我没有选择retu ...

  6. Easyui主要组件用法

    Easyui主要组件用法说明: 1.  combogrid用法 说明:combogrid可提供翻页列表的数据选择并可进行数据的过滤查询(查询的传人参数为q,可在控制器中获取这个参数传过来的值,下面的示 ...

  7. SqlSever基础 except 差集 前一个结果中不含有后一个结果的元素

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  8. 编写Music类

    package a; public class Instrument { public void play() { System.out.println("弹奏乐器"); } } ...

  9. UVA 10534 三 Wavio Sequence

    Wavio Sequence Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Sta ...

  10. vs2012 提示 未能正确加载 "Visual C++ Language Manager Package" 包 的解决办法

    1.点击vs2012菜单栏 工具-> Visual Studio 命令提示 打开命令窗口 2.输入命令 "devenv /Setup" 3.重新打开vs2012