Maximum number, GCD condition (CodeChef)

来源:互联网 发布:ubuntu没有wifi列表 编辑:程序博客网 时间:2024/06/07 19:45

题目:http://www.codechef.com/problems/ANUGCD/


给一个数组,m个查询,查询格式G X Y,查询[X,Y]区间中的数与G的GCD>1,且要最大的,外加这个数的次数。

想法:对每个素数建一个线段树,一开始做的时候,只建了sqrt(10W)的线段树,其他大的素数,就暴力,结果TLE,后来就干脆对每个<10W的素数建树,静态数组开不下,开的动态的。

#include <stdio.h>#include <string.h>#include <map>#include <vector>#include <ctime>#include <math.h>#include <algorithm>using namespace std;inline int input(){    int ret=0;    char c=getchar();    while(c<'0'||c>'9') c=getchar();    while(c>='0'&&c<='9'){        ret=ret*10+c-'0';        c=getchar();    }    return ret;}inline void output(int x){    if(x<0){        putchar('-');        x=-x;    }    int len=0,data[10];    while(x){        data[len++]=x%10;        x/=10;    }    if(!len)        data[len++]=0;    while(len--)        putchar(data[len]+48);}#define N 100005#define L t<<1#define R t<<1|1typedef pair<int,int> ii;int a[N],n,m,g,x,y;vector<int>pp[N];bool pri[N];int p[N/10];int pos[N];int cnt=0;inline void init(){    memset(pri,0,sizeof(pri));    pri[0]=pri[1]=1;    for(int i=2;i<=100000;i++){        if(!pri[i]){            pos[i]=cnt;            p[cnt++]=i;            for(int j=i*2;j<=100000;j+=i) pri[j]=1;        }    }}struct node{    node* l;    node* r;    int x,y;    ii val;};inline void push_up(node *t){    if(t->l->val.first > t->r->val.first){        t->val = t->l->val;    }    else if(t->l->val.first < t->r->val.first){        t->val = t->r->val;    }    else{        t->val = t->l->val;        t->val.second += t->r->val.second;    }}inline void build(node *t,int l,int r,int id){    t->x = l;    t->y = r;    if(l == r){        t->val=make_pair(a[pp[id][l-1]],1);    }    else{        int mid=(l+r)>>1;        t->l = new node();        t->r = new node();        build(t->l,l,mid,id);        build(t->r,mid+1,r,id);        push_up(t);    }}inline ii query(node *t,int l,int r){    int x = t->x , y = t->y;    if(x>=l && y<=r){        return t->val;    }    if(x>r || y<l){        return make_pair(-1,0);    }    int mid=(x+y)>>1;    if(r<=mid) return query(t->l,l,r);    else if(l>mid) return query(t->r,l,r);    else{        ii a=query(t->l,l,mid);        ii b=query(t->r,mid+1,r);        if(a.first > b.first) return a;        else if(a.first < b.first) return b;        else{            a.second += b.second;            return a;        }    }}inline int search(int id,int x){    int s=0,t=pp[id].size()-1;    while(s<=t){        int mid=(s+t)>>1;        int val=pp[id][mid];        if(val == x) return mid;        if(val <x )s=mid+1;        else t=mid-1;    }    return s;}int main(){    init();    node *root[cnt+1];    for(int i=0;i<=cnt;i++){        root[i] = new node();    }    n=input(),m=input();    for(int i=1;i<=n;i++){        a[i]=input();        int w=a[i];        for(int j=0;j<cnt;j++){            if(pri[w] == 0){                pp[pos[w]].push_back(i);                w=1;                break;            }            if(w%p[j] == 0){                pp[j].push_back(i);                while(w>1 && w%p[j]==0) w/=p[j];                if(w<=1) break;            }        }    }    for(int i=0;i<cnt;i++){        int S=pp[i].size();        if(S==0) continue;        build(root[i],1,S,i);    }    while(m--){        g=input(),x=input(),y=input();        ii ans=make_pair(-1,-1);        for(int i=0;i<cnt;i++){            if(pri[g] == 0){                int ind=pos[g];                int l=search(ind,x)+1;                int r=search(ind,y);                if(r>=pp[ind].size()) r=pp[ind].size();                else{                    if(pp[ind][r]>y) r--;                    r+=1;                }                if(r>=l){                    ii tmp=query(root[ind],l,r);                    if(tmp.first > ans.first){                        ans=tmp;                    }                }                g=1;                break;            }            if(g%p[i]==0){                int l=search(i,x)+1;                int r=search(i,y);                if(r>=pp[i].size()) r=pp[i].size();                else{                    if(pp[i][r]>y) r--;                    r+=1;                }                if(r>=l){                    ii tmp=query(root[i],l,r);                    if(tmp.first > ans.first){                        ans=tmp;                    }                }                while(g>1 && g%p[i]==0) g/=p[i];                if(g<=1) break;            }        }        if(ans.first<=0 || ans.second<=0) puts("-1 -1");        else{            output(ans.first),putchar(' ');            output(ans.second),putchar('\n');        }    }    return 0;}


0 0