zoukankan      html  css  js  c++  java
  • CF474 F. Ant colony

    题目传送门:https://codeforces.com/problemset/problem/474/F

    题目大意:
    给定一串长度为(n)的序列(A),记子串([l_i,r_i])中,(v_k+1=sumlimits_{j=l_i}^{r_i}[A_j\%A_k==0],(l_ileqslant kleqslant r_i)),((v_k+1)是为了包含了自己(\%)自己的情况)

    现有(m)组询问,每次询问子串([l_i,r_i])中,(v_k eq r_i-l_i)的数的个数


    考虑什么数才会有(v_k=r_i-l_i),显然是([l_i,r_i])所有数的最大公约数

    故我们求出([l_i,r_i])的最大公约数后,再求其在([l_i,r_i])中的出现次数即可

    一个用线段树维护,一个用主席树维护,码就完事了

    /*program from Wolfycz*/
    #include<map>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define Fi first
    #define Se second
    #define ll_inf 1e18
    #define MK make_pair
    #define sqr(x) ((x)*(x))
    #define pii pair<int,int>
    #define int_inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    template<typename T>inline T frd(T x){
    	int f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    template<typename T>inline T read(T x){
    	int f=1; char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)	putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e5,M=5e6;
    int V[N+10],list[N+10];
    int gcd(int a,int b){return !b?a:gcd(b,a%b);}
    struct S1{
    	#define ls (p<<1)
    	#define rs (p<<1|1)
    	int Tree[(N<<2)+10];
    	void update(int p){Tree[p]=gcd(Tree[ls],Tree[rs]);}
    	void Build(int p,int l,int r){
    		if (l==r){
    			Tree[p]=list[V[l]];
    			return;
    		}
    		int mid=(l+r)>>1;
    		Build(ls,l,mid);
    		Build(rs,mid+1,r);
    		update(p);
    	}
    	int Query(int p,int l,int r,int L,int R){
    		if (L<=l&&r<=R)	return Tree[p];
    		int mid=(l+r)>>1,res=0;
    		if (L<=mid)	res=gcd(res,Query(ls,l,mid,L,R));
    		if (R>mid)	res=gcd(res,Query(rs,mid+1,r,L,R));
    		return res;
    	}
    	#undef ls
    	#undef rs
    }ST;//Segment Tree
    int Root[N+10];
    struct S2{
    	int ls[M+10],rs[M+10],Cnt[M+10],tot;
    	void insert(int p,int &k,int l,int r,int x){
    		Cnt[k=++tot]=Cnt[p]+1;
    		ls[k]=ls[p],rs[k]=rs[p];
    		if (l==r)	return;
    		int mid=(l+r)>>1;
    		if (x<=mid)	insert(ls[p],ls[k],l,mid,x);
    		if (x>mid)	insert(rs[p],rs[k],mid+1,r,x);
    	}
    	int Query(int p,int k,int l,int r,int x){
    		if (l==r)	return Cnt[k]-Cnt[p];
    		int mid=(l+r)>>1;
    		if (x<=mid)	return Query(ls[p],ls[k],l,mid,x);
    		if (x>mid)	return Query(rs[p],rs[k],mid+1,r,x);
    		return 0;
    	}
    }CT;//Chairman Tree
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	int n=read(0);
    	for (int i=1;i<=n;i++)	list[i]=V[i]=read(0);
    	sort(list+1,list+1+n);
    	int T=unique(list+1,list+1+n)-list-1;
    	for (int i=1;i<=n;i++)	V[i]=lower_bound(list+1,list+1+T,V[i])-list;
    	ST.Build(1,1,n);
    	for (int i=1;i<=n;i++)	CT.insert(Root[i-1],Root[i],1,T,V[i]);
    	int m=read(0);
    	for (int i=1;i<=m;i++){
    		int l=read(0),r=read(0),res=ST.Query(1,1,n,l,r);
    		int pos=lower_bound(list+1,list+1+T,res)-list;
    		int Cnt=list[pos]!=res?0:CT.Query(Root[l-1],Root[r],1,T,pos);
    		printf("%d
    ",r-l+1-Cnt);
    	}
    	return 0;
    }
    
    作者:Wolfycz
    本文版权归作者和博客园共有,欢迎转载,但必须在文章开头注明原文出处,否则保留追究法律责任的权利
  • 相关阅读:
    剑指offer编程题66道题 26-35
    剑指offer编程题66道题 1-25
    springboot的自动配置
    用智能的编译器来防错
    实现迭代器的捷径
    结束C#2的讲解:最后的一些特性
    进入快速委托通道
    可空类型
    用泛型实现参数化类型
    C#1所搭建的核心基础
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/14963405.html
Copyright © 2011-2022 走看看