zoukankan      html  css  js  c++  java
  • ICPCCamp 2017 I Coprime Queries

    给出一个长度为(n)的正整数序列(a)(m)次询问(l,r,x),问(max{i|iin[l,r],gcd(a_i,x)=1})

    (n,m,a_ile 10^5)

    分析

    这个题很妙啊。

    二分答案,问题变成判断在一个区间([l,r])中是否存在(gcd(a_i,x)=1),变成判断([l,r])中有多少个(gcd(a_i,x) e 1),我们要计算的就是:

    [egin{aligned} ret&=sum _{i=L}^R[gcd(a_i,x) e 1] \ &=left[sum _{i=L}^Rsum _{d|x,d|a_i}mu (d) ight]=0 \ end{aligned} ]

    这个怎么算呢?我们注意到,如果(d)含有平方因子,那么(mu (d))必定是0,不需要去计算,所以我们只需要统计无平方因子数。可以发现,对于(10^5)以内的数,它的无平方因子非常少,最多为64个((2*3*5*7*11*13*17>10^5)),所以直接枚举就好了。对于([1,10^5])内的所有无平方因子数,我们记录含有它的每个(a_i)的下标(i),每次对于询问的(x)在区间内二分计算即可。

    复杂度约为(O(64nlog^2n))

    代码

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    typedef long long giant;
    int read() {
    	int x=0,f=1;
    	char c=getchar();
    	for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    	for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const int maxn=1e5+1;
    int a[maxn],pm[maxn],ps=0,mu[maxn],from[maxn];
    int sf[maxn],id[maxn],fs=0;
    bool np[maxn];
    vector<int> vec[maxn],my[maxn];
    int many(int l,int r,int d) {
    	++r;
    	int fx=lower_bound(vec[d].begin(),vec[d].end(),l)-vec[d].begin();
    	int fy=lower_bound(vec[d].begin(),vec[d].end(),r)-vec[d].begin();
    	return fy-fx;
    }
    bool ok(int l,int r,int x) {
    	int ret=0;
    	for (int d:my[x]) {
    		int gs=many(l,r,d);
    		ret+=mu[d]*gs;
    	}
    	return ret;
    } 
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("test.in","r",stdin);
    	freopen("my.out","w",stdout);
    #endif
    	int n=read(),q=read();
    	mu[1]=1;
    	for (int i=2;i<maxn;++i) {
    		if (!np[i]) pm[++ps]=i,mu[i]=-1,from[i]=1;
    		for (int j=1;j<=ps && (giant)pm[j]*i<maxn;++j) {
    			int tmp=pm[j]*i;
    			from[tmp]=i;
    			np[tmp]=true;
    			if (i%pm[j]==0) {
    				mu[tmp]=0;
    				break;
    			}
    			mu[tmp]=-mu[i];
    		}
    	}
    	for (int i=1;i<maxn;++i) if (mu[i]) sf[++fs]=i,id[i]=fs;
    	for (int i=1;i<maxn;++i) {
    		for (int j=1;(giant)j*j<=i;++j) if (i%j==0) {
    			if (mu[j]) my[i].push_back(j);
    			if ((giant)j*j!=i && mu[i/j]) my[i].push_back(i/j);
    		}
    	}
    	for (int i=1;i<=n;++i) {
    		int x=a[i]=read();
    		for (int d:my[x]) vec[d].push_back(i);
    	}
    	while (q--) {
    		int l=read(),r=read(),x=read(),mid,ans=-1;
    		while (l<=r) {
    			int mid=l+r>>1;
    			if (ok(mid,r,x)) l=mid+1,ans=mid; else r=mid-1;
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    3.6 批量维护来源准则/查看来源准则
    3.5 供货比例(来源准则)控制
    3.4 新供应商引入
    3.3 集团化采购管理
    3.2 采购管理目标
    3.1 采购管理规划
    2.8 生产辅料管理
    2.7 车间任务的批量移动和批量完工入库
    2.6 自动更新车间任务的供应类型和完工子库
    2.5 总装与部装跟单任务的同步发放
  • 原文地址:https://www.cnblogs.com/owenyu/p/6774049.html
Copyright © 2011-2022 走看看