题目链接: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. [Unity3D]MonoBehaviour函数介绍

    原文地址: http://www.cocos2dev.com/?p=486 Unity中的脚本都是继承自MonoBehaviour. 一.基础函数: 创建脚本就默认的update.start方法:(这 ...

  2. ubuntu-E:Encountered a section with no Package: header的解决办法

    刚才打开ubuntu,我的版本是12.04.正想使用sudo apt-get install build-essential 时,出现了如下错误: E:Encountered a section wi ...

  3. easyui datagrid 可过滤行的数据表格 导出

    //过滤栏表格导出数据                  /* xukf                 * id datagrid id                 * url Action 路 ...

  4. oracle中的自动增长

    create table test( id int not null primary key, name varchar2(20), sex int) ; create sequence t -> ...

  5. U3D UGUI学习4 - Text

    1.对应NGUI的四种文字显示模式 Shrink Content 对应NGUI第一种模式     勾选Best Fit 但似乎有一个Bug,文字过多的时候会爆框.解决方法是改变Line Spacing ...

  6. The Blacksmith学习的相关资源

    1.Unity官网的Blacksmith主页 https://unity3d.com/pages/the-blacksmith 2.WRINKLE MAPS IN THE BLACKSMITH 褶皱贴 ...

  7. Infragistics 汉化

    Infragistics 汉化实例: Infragistics.Shared.ResourceCustomizer rc=Infragistics.Win.UltraWinGrid.Resources ...

  8. C语言中的const

    今天探讨const,首先来说是将变量常量化.为什么要将变量常量化,原因有诸多好处有诸多.比如可以使数据更加安全不会被修改! 但是这个词有几个点要注意,那就是他究竟修饰了谁? 1.const int a ...

  9. Dungeon Master bfs

    time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u POJ 2251 Descriptio ...

  10. 从原理上搞定编码-- Base64编码

    BASE64是一种编码方式,通常用于把二进制数据编码为可写的字符形式的数据.这是一种可逆的编码方式.编码后的数据是一个字符串,其中包含的字符为:A-Z.a-z.0-9.+./共64个字符:26 + 2 ...