筛法,区间问题(RGCDQ,HDU 5317)

来源:互联网 发布:小智淘宝店网址是多少 编辑:程序博客网 时间:2024/06/05 19:09

从一开始学筛法及其优化的时候就只是一知半解,所以需要用到其变化的时候就开始暴露问题。

顺便学了一下线性筛:

http://blog.csdn.net/xl2015190026/article/details/72859366


理应想到应用区间问题的解法的,思路都是前缀和。只不过跟数位有关的问题就用数位计数DP求前缀和,最简单的前缀和就是O(n)加起来。

这里的前缀和是指个数的前缀和,也就是所谓的一维差分算法,用于快速找区间内满足条件的数的个数。

区间问题是指多次询问一个区间里面满足特定条件的数的个数。

本题不是区间问题,因为既不是问数的个数,也不是单纯的只考虑每一个数,因此前缀和或是线段树都没有办法很好的解决。

但是由于题目的特殊性,所以可以转化成区间问题再来讨论求解。


代码

#include<stdio.h>#include<math.h>#include<vector>#include<algorithm>#include<string.h>using namespace std;const int maxn = 1000010;int F[maxn];vector<int>vec[10];int cnt[10];void init(){    for(int i=2;i<maxn;i++) if(!F[i])        for(int j=i;j<maxn;j+=i) F[j]++;    for(int i=2;i<maxn;i++) if(F[i]>=3) vec[F[i]].push_back(i);}int solve(){    int L,R;    scanf("%d %d",&L,&R);    int l,r;    l=lower_bound(vec[7].begin(),vec[7].end(),L)-vec[7].begin();    r=upper_bound(vec[7].begin(),vec[7].end(),R)-vec[7].begin();    if(r-l>=2) return 0*puts("7");    l=lower_bound(vec[6].begin(),vec[6].end(),L)-vec[6].begin();    r=upper_bound(vec[6].begin(),vec[6].end(),R)-vec[6].begin();    if(r-l>=2) return 0*puts("6");    l=lower_bound(vec[5].begin(),vec[5].end(),L)-vec[5].begin();    r=upper_bound(vec[5].begin(),vec[5].end(),R)-vec[5].begin();    if(r-l>=2) return 0*puts("5");    l=lower_bound(vec[4].begin(),vec[4].end(),L)-vec[4].begin();    r=upper_bound(vec[4].begin(),vec[4].end(),R)-vec[4].begin();    if(r-l>=2) return 0*puts("4");    l=lower_bound(vec[3].begin(),vec[3].end(),L)-vec[3].begin();    r=upper_bound(vec[3].begin(),vec[3].end(),R)-vec[3].begin();    if(r-l>=2) return 0*puts("3");    memset(cnt,0,sizeof(cnt));    for(int i=L;i<=R;i++) cnt[F[i]]++;    if(cnt[6]&&cnt[3]) return 0*puts("3");    if(cnt[2]&&cnt[4]) return 0*puts("2");    if(cnt[2]&&cnt[6]) return 0*puts("2");    if(cnt[4]&&cnt[6]) return 0*puts("2");    if(cnt[2]>=2) return 0*puts("2");    return 0*puts("1");}int main(){    init();    //for(int i=0;i<=1000;i++) printf("F(%d):%d\n",i,F[i]);    int T;    scanf("%d",&T);    while(T--) solve();    return 0;}


原创粉丝点击