多校3-1002 HDU 5317

来源:互联网 发布:网站美工教程 编辑:程序博客网 时间:2024/04/29 23:03

RGCDQ

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 644    Accepted Submission(s): 305


Problem Description
Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and more interesting things about GCD. Today He comes up with Range Greatest Common Divisor Query (RGCDQ). What’s RGCDQ? Please let me explain it to you gradually. For a positive integer x, F(x) indicates the number of kind of prime factor of x. For example F(2)=1. F(10)=2, because 10=2*5. F(12)=2, because 12=2*2*3, there are two kinds of prime factor. For each query, we will get an interval [L, R], Hdu wants to know maxGCD(F(i),F(j))(Li<jR)
 

Input
There are multiple queries. In the first line of the input file there is an integer T indicates the number of queries.
In the next T lines, each line contains L, R which is mentioned above.

All input items are integers.
1<= T <= 1000000
2<=L < R<=1000000
 

Output
For each query,output the answer in a single line.
See the sample for more details.
 

Sample Input
22 33 5
 

Sample Output
11
 

题意:定义F(X)代表X由多少个不同的质因数构成,给定L R 求 MAX(F[i),F[j]) L<=I,j<=R.

思路:X最大100W ,首先处理出所有的F(x)就好了对吧------->1.打个100W以内的素数表 2.对于每个x进行质因子分解,用个fac数组存枚举的x有多少个不同的质因子构成就好了

            接着欣然发现F(x)最大只有7。。由于T=100W,所以不可能O(n)扫一遍统计给定的区间里每个F(x) x=1-7各出现了多少次,所以很容易想到用一个二维数组维护一下

            当前的区间的f(x)出现了多少次的比如res[i][j]代表i这个数在区间1-j一共出现了多少次,到时候询问LR区间内最大值 直接res[i][R]-res[i][L-1]就能知道i这个数在L-R内出现

            多少次了,知道了有啥用- -这不是废话么,从7枚举到1,如果一旦出现两个相减的值大于等于2,说明L-R内i出现过至少两次,所以选这两个数出来显然GCD最大啊- -。

            接着就是一些细节的处理咯,详见代码2333.dabiao的代码风格被学霸给强行改成他那样的了- -就是因为一开始质因子分解写挫了2333

#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>using namespace std;const long long N=(1<<20)+5;long long n;bool is_prime[N];int prime[N];int fac[N];int cnt;int res[10][N];void dabiao() {  memset(is_prime, 0, sizeof(is_prime));  memset(fac,0,sizeof(fac));  is_prime[0]=is_prime[1]=1;  for(int i=0;i<N;i++) {    if(is_prime[i]==1)      continue;    for(long long j=1LL * i*i;j<N;j+=i)      is_prime[j]=1;  }  int cnt=0;  for(int i=0;i<N;i++)      if(!is_prime[i])          prime[cnt++]=i;  //  for(int i=2;i<N;i++) {    int tmp=i;    for(int j=0; j < cnt && tmp >= 1LL * prime[j] * prime[j]; j++) {//这里好久没写 一开始写了个tmp!=1就继续分解,导致复杂度高成马= =      if(tmp%prime[j]==0) {        fac[i]++;        while(tmp%prime[j]==0)          tmp/=prime[j];      }    }    if (tmp > 1)      fac[i]++;//还有可能是一个大质数哦-,-  }    for(int i=1; i<=8; i++)    {        res[i][1] = 0;//每个数从1-1肯定只出现过0次啦。因为从2开始2333    }    for(int j=2; j<N; j++)    {        for(int i=1;i<=8;i++)        {            int x=fac[j];            if(x==i)//如果此时的这个j对应的fj跟枚举的i相等                res[i][j]=res[i][j-1]+1;//显然i这个数从1-j这个区间内出现的次数等于1-j-1出现的次数+1咯            else                res[i][j]=res[i][j-1];//否则不变对吧- -        }    }}int main(){    dabiao();    int t;    scanf("%d",&t);    int l,r;    while(t--)    {        scanf("%d%d",&l,&r);        int pos;        for(int i=8;i>=1;i--)        {            if(res[i][r]-res[i][l-1]>=2)            {                pos=i;                break;            }        }        printf("%d\n",pos);    }    return 0;}

全场的贡献貌似就是这题了- -。 11水题鑫神随手切 04模拟把那个有毒的输入弄好了就变成SB题了。。我就不写了,留给我妹子去写题解去让她骗一发浏览量233333333

不过她代码能力比我强啊OTL都可以我给她思路让她边写,我在旁边帮她注意细节了- -||| 诶好像这分工反了吧QAQ 管它呢- -继续打好后面的多校吧2333。






0 0
原创粉丝点击