hdu 5317 RGCDQ(前缀和)
题目链接: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(前缀和)的更多相关文章
- 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 ...
- HDU 5317 RGCDQ(素数个数 多校2015啊)
题目链接:pid=5317" target="_blank">http://acm.hdu.edu.cn/showproblem.php?pid=5317 Prob ...
- ACM学习历程—HDU 5317 RGCDQ (数论)
Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more an ...
- HDU 5317 RGCDQ (数论素筛)
RGCDQ Time Limit: 3000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Submit Status ...
- 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 ...
- HDU 5317 RGCDQ (质数筛法,序列)
题意:从1~1000,000的每个自然数质因子分解,不同因子的个数作为其f 值,比如12=2*2*3,则f(12)=2.将100万个数转成他们的f值后变成新的序列seq.接下来T个例子,每个例子一个询 ...
- HDU 5317 RGCDQ
题意:f(i)表示i的质因子个数,给l和r,问在这一区间内f(i)之间任意两个数最大的最大公倍数是多少. 解法:先用筛法筛素数,在这个过程中计算f(i),因为f(i)不会超过7,所以用一个二维数组统计 ...
- 2015 HDU 多校联赛 5317 RGCDQ 筛法求解
2015 HDU 多校联赛 5317 RGCDQ 筛法求解 题目 http://acm.hdu.edu.cn/showproblem.php? pid=5317 本题的数据量非常大,測试样例多.数据 ...
- hdu 5317 合数分解+预处理
RGCDQ Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
随机推荐
- Python 字典(Dictionary)
字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式如下所示: d = ...
- GPS定位原理
多分钟吧(有人认为美国对其本土覆盖的GPS信号实行不同码率因此纯GPS定位也会很快,谁有美国朋友不妨让他拔卡试试)!因为美版机型其GPS模块的数据处理软件部分与欧版机型是不同的,欧版机型的数据处理软件 ...
- MultiSelectComboBox(一)
1. MultiSelectComboBox.xaml <UserControl x:Class="MultiSelectComboBox.MultiSelectComboBox&qu ...
- drawer principle in Combinatorics
Problem 1: Given an array of real number with length (n2 + 1) A: a1, a2, ... , an2+1. Prove that th ...
- HDU(1175),连连看,BFS
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1175 越学越不会,BFS还是很高级的. 连连看 Time Limit: 20000/100 ...
- Python_cmd的各种实现方法及优劣(subprocess.Popen, os.system和commands.getstatusoutput)
http://blog.csdn.net/menglei8625/article/details/7494094
- 编译android源码官方教程(2)建立编译环境「linux & mac osx」
https://source.android.com/source/initializing.html Establishing a Build Environment IN THIS DOCUMEN ...
- 【Java】Float计算不准确
大家可能都遇到过,float在计算某些值时,会有不准确的情况. 比如如下情况: > 计算不准确 package com.nicchagil.study.java.demo.No10float计算 ...
- (1)定义一个接口CanFly,描述会飞的方法public void fly(); (2)分别定义类飞机和鸟,实现CanFly接口。 (3)定义一个测试类,测试飞机和鸟,在main方法中创建飞机对象和鸟对象, 再定义一个makeFly()方法,其中让会飞的事物飞。并在main方法中调用该方法, 让飞机和鸟起飞。
package b; public interface CanFly { public void fly(); } package b; public class FeiJi implements C ...
- FreeSWITCH第三方库(其他)的简单介绍(三)
FreeSWITCH使用了大量的第三方库,本文档主要介绍关联相关库的信息: 音频相关库的信息介绍参考:http://www.cnblogs.com/yoyotl/p/5486753.html 视频相关 ...