HDU 4777 Rabbit Kingdom

来源:互联网 发布:scara机械手编程手册 编辑:程序博客网 时间:2024/05/14 08:01

杭州区域赛的题目


题意:

给定区间[l,r] ,求[l,r]内有多少个数满足与区间内其他数都互质。


思路:

处理出每个数,最左边能互质到的位置L[i],以及右边R[i]。(具体方法看代码)

然后用树状数组维护区间的覆盖,按l离线查询。

然后从左往右扫。对于当前位置p,找出所有L[i]==p的数。然后i位置+1,R[i]+1的位置-1。因为p以及p以后的位置,这个L[i]都能覆盖到。

离开位置p的时候,要把p位置这个数的覆盖去掉。即p位置-1,R[p]+1的位置+1。

如果p位置上有查询,那么sum(r)就是答案。

总复杂度O(nlogn)


这份代码C++能AC,G++MEL。。。其实C++也要32760KB,因为用了很多vector,加上数据有20W,vector实际比存储的要大。虽然理论计算是不会MLE的。

code:

#include <algorithm>#include <iostream>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <string>#include <math.h>#include <vector>#include <queue>#include <stack>#include <cmath>#include <list>#include <set>#include <map>using namespace std;    #define N  200010#define ll long long#define ALL(x)     x.begin(),x.end()#define CLR(x,a) memset(x,a,sizeof(x))typedef pair<int,int> PI;const int INF=0x3fffffff;const int MOD   =1000000007;const double EPS=1e-7;class BIT{private:    int sum[N],n;    public:    void init(int n){        this->n=n;        fill(sum+1,sum+n+1,0);    }    void add(int i,int x){        for(;i<=n;i+=-i&i) sum[i]+=x;    }    int get(int i){        int ans=0;        for(;i>=1;i-=-i&i) ans+=sum[i];        return ans;    }}T;vector<PI > Q[N];vector<int> pos[N],prm[N];int ans[N],l[N],r[N],idx[N],a[N];void solve(int n,int d[]){    CLR(idx,0);    for(int i=1;i<=n;i++){        d[i]=0;        for(int j=0;j<prm[a[i]].size();j++){            d[i]=max(d[i],idx[prm[a[i]][j]]);            idx[prm[a[i]][j]]=i;        }        d[i]++;    }}void pretreat(int n){    solve(n,l);    reverse(a+1,a+n+1);    solve(n,r);    reverse(a+1,a+n+1);    for(int i=1,j=n;i<j;i++,j--) swap(r[i],r[j]);    for(int i=1;i<=n;i++) r[i]=n-r[i]+2;    for(int i=1;i<=n;i++) pos[l[i]].push_back(i);}bool vis[N];int main(){    int n,m;    for(int i=2;i<N;i++) if(!vis[i]){        for(ll j=1ll*i*i;j<N;j+=i) vis[i]=true;        for(int j=i;j<N;j+=i) prm[j].push_back(i);    }    while(~scanf("%d%d",&n,&m),n||m){        for(int i=1;i<=n;i++){            scanf("%d",a+i);            pos[i].clear(), Q[i].clear();        }        for(int i=0;i<m;i++){            int l,r;            scanf("%d%d",&l,&r);            Q[l].push_back(make_pair(r,i));        }        pretreat(n);        T.init(n+1);        for(int i=1;i<=n;i++){            for(int j=0;j<pos[i].size();j++){                int p=pos[i][j];                T.add(p,1);                T.add(r[p],-1);            }            for(int j=0;j<Q[i].size();j++)                 ans[Q[i][j].second]=T.get(Q[i][j].first);            T.add(i,-1);            T.add(r[i],1);        }        for(int i=0;i<m;i++) printf("%d\n",ans[i]);    }    return 0;}



0 0
原创粉丝点击