hdu 5317 筛法+前缀和+暴力

由函数f的定义可以联想到:可以在筛素数(对于普通筛法,每个合数会被自己的素因子筛去一次)的过程中获得函数的值,然后可以发现2,3,5,7,11,13,17,19乘起来已经超过了100W,所以对于100W及以内的数,函数值最多为7.

然后求出前缀和,对于每一个询问,统计出每个区间内函数值为1-7的数字的个数暴力循环获得max gcd。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5
 6 const int N = 1000001;
 7 const int M = 8;
 8 int f[N];
 9 int sum[M][N];
10 int a[M];
11 int pn;
12
13 void init()
14 {
15     memset( f, 0, sizeof(f) );
16     for ( int i = 2; i < N; i++ )
17     {
18         if ( !f[i] )
19         {
20             f[i] = 1;
21             for ( int j = i + i; j < N; j += i )
22             {
23                 f[j]++;
24             }
25         }
26     }
27     memset( sum, 0, sizeof(sum) );
28     for ( int i = 0; i < N; i++ )
29     {
30         sum[f[i]][i] = 1;
31     }
32     for ( int i = 1; i < M; i++ )
33     {
34         for ( int j = 1; j < N; j++ )
35         {
36             sum[i][j] += sum[i][j - 1];
37         }
38     }
39 }
40
41 int gcd( int x, int y )
42 {
43     return y ? gcd( y, x % y ) : x;
44 }
45
46 int main ()
47 {
48     init();
49     int t;
50     scanf("%d", &t);
51     while ( t-- )
52     {
53         int l, r;
54         scanf("%d%d", &l, &r);
55         int ans = -1;
56         pn = 0;
57         for ( int i = 1; i < M; i++ )
58         {
59             if ( sum[i][r] - sum[i][l - 1] > 1 )
60             {
61                 ans = i;
62             }
63             else if ( sum[i][r] - sum[i][l - 1] == 1 )
64             {
65                 a[pn++] = i;
66             }
67         }
68         for ( int i = 0; i < pn; i++ )
69         {
70             for ( int j = i + 1; j < pn; j++ )
71             {
72                 int tt = gcd( a[i], a[j] );
73                 if ( tt > ans ) ans = tt;
74             }
75         }
76         printf("%d\n", ans);
77     }
78     return 0;
79 }
时间: 2024-10-24 11:32:33

hdu 5317 筛法+前缀和+暴力的相关文章

hdu 5317 RGCDQ(前缀和)

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

HDU 5317 RGCDQ (合数分解+预处理)

题目链接:HDU 5317 RGCDQ 题意:定义函数F(x)为x的不同的素因子且小于等于x的个数,询问[l,r]区间中gcd(F(i),F(j))的最大值. 思路:暴力预处理出所有的合数分解结果,发现F(x)最大也只有7,之后就是暴力求出所有1到7出现次数的前缀和.询问的时候就打到O(1)了. AC代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #

hdu 5317 合数分解+预处理

RGCDQ Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2818    Accepted Submission(s): 1108 Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and m

HDU 4930 Fighting the Landlords(暴力枚举+模拟)

HDU 4930 Fighting the Landlords 题目链接 题意:就是题中那几种牌型,如果先手能一步走完,或者一步让后手无法管上,就赢 思路:先枚举出两个人所有可能的牌型的最大值,然后再去判断即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Player { int rank[15]; } p1, p2; int t, h

hdu 1399 Starship Hakodate-maru (暴力搜索)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1399 题目大意:找到满足i*i*i+j*(j+1)*(j+2)/6形式且小于等于n的最大值. 1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 int main() 7 { 8 int n; 9 while(scanf("%d",&n),n) 10 { 11 int j,

HDU 5280 Senior&#39;s Array (暴力,水)

题意:给一个数列,再给一个数字p,要求p一定要替换掉数列中的一个元素,然后求最大连续子序列之和. 思路:1000*1000的复杂度,O(n*n) .就是每个都试,然后求和. 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define pii pair<int,int> 4 #define INF 0x7f7f7f7f 5 using namespace std; 6 const int N=2000; 7 int a[N]

hdu 4932 Miaomiao&#39;s Geometry(暴力)

题目链接:hdu 4932 Miaomiao's Geometry 题目大意:在x坐标上又若干个点,现在要用若干条相等长度的线段覆盖这些点,若一个点被一条线段覆盖,则必须在这条线的左端点或者是右端点,并且各个线段放的位置不能又重叠,求最大长度. 解题思路:这题有坑点,比赛的时候o(n)的算法去寻找两点之间最短距离.但起始这样是不行的,比如-1 0 10 12 18 20,这样维护过去的话,最短应该是12~18,长度为6,这段线段可以覆盖12和18的点,然后-1和20又在两端.于是只有0和10两点

hdu 4876 ZCC loves cards(暴力)

题目链接:hdu 4876 ZCC loves cards 题目大意:给出n,k,l,表示有n张牌,每张牌有值.选取其中k张排列成圈,然后在该圈上进行游戏,每次选取m(1≤m≤k)张连续的牌,取牌上值的亦或和.要求找到一个圈,使得L~R之间的数都可以得到,输出R.如果R < L输出0. 解题思路:暴力,首先预处理出来每种选取的亦或值,然后在该基础上从可以组成L的状态中挑选一个,L+1的状态中挑取一个,知道说总的挑取出所有状态中选中的牌的个数大于K为值,然后用全排序去查找最大的R. #includ

hdu 4932 Miaomiao&#39;s Geometry 暴力枚举

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4932 Miaomiao's Geometry Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 694    Accepted Submission(s): 180 Problem Description There are N point