zoukankan      html  css  js  c++  java
  • 【刷题】HDU 5869 Different GCD Subarray Query

    Problem Description

    This is a simple problem. The teacher gives Bob a list of problems about GCD (Greatest Common Divisor). After studying some of them, Bob thinks that GCD is so interesting. One day, he comes up with a new problem about GCD. Easy as it looks, Bob cannot figure it out himself. Now he turns to you for help, and here is the problem:

    Given an array (a) of (N) positive integers (a_1, a_2, cdots a_{N-1}, a_N) ; a subarray of (a) is defined as a continuous interval between (a_1) and (a_N) .In other words,(a_i, a_{i+1}, cdots, a_{j-1}, a_j) is a subarray of (a), for (1le ile jle N).For a query in the form ((L, R)) , tell the number of different GCDs contributed by all subarrays of the interval ([L, R]).

    Input

    There are several tests, process till the end of input.

    For each test, the first line consists of two integers (N) and (Q), denoting the length of the array and the number of queries, respectively. (N) positive integers are listed in the second line, followed by (Q) lines each containing two integers (L,R) for a query.

    You can assume that

    (1≤N,Q≤100000)

    (1≤a_i≤1000000)

    Output

    For each query, output the answer in one line.

    Sample Input

    5 3
    1 3 4 6 9
    3 5
    2 5
    1 5

    Sample Output

    6
    6
    6

    Description(CHN)

    给定一个数列,多次询问,每次询问 (L,R),求 ([L,R]) 中所有子区间的 (gcd) 有多少种

    Solution

    预处理对于数列中的每个位置,对于它为 (R) 的所有区间中不同的 (gcd) 出现的最右边的 (L) 是什么。这个东西直接在上一个位置的基础上枚举就好了
    将询问离线
    我们用BIT维护每种 (gcd) 出现的区间的 (L) 的最右的位置在哪里,然后就用差分计算答案就好了

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXN=300000+10;
    int n,m,a[MAXN],ans[MAXN];
    std::map<int,int> M;
    std::vector< std::pair<int,int> > V[MAXN],query[MAXN];
    struct BIT{
    	int C[MAXN];
    	inline void init()
    	{
    		memset(C,0,sizeof(C));
    	}
    	inline int lowbit(int x)
    	{
    		return x&(-x);
    	}
    	inline void add(int x,int k)
    	{
    		while(x<=n)C[x]+=k,x+=lowbit(x);
    	}
    	inline int sum(int x)
    	{
    		if(!x)return 0ll;
    		int res=0;
    		while(x>0)res+=C[x],x-=lowbit(x);
    		return res;
    	}
    };
    BIT T;
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    #define ft first
    #define sd second
    int main()
    {
    	while(scanf("%d%d
    ",&n,&m)!=EOF)
    	{
    		for(register int i=1;i<=n;++i)read(a[i]),V[i].clear(),query[i].clear();
    		T.init();M.clear();
    		V[1].push_back(std::make_pair(1,a[1]));
    		for(register int i=2;i<=n;++i)
    		{
    			int now=a[i];V[i].push_back(std::make_pair(i,a[i]));
    			for(register int j=0,lt=V[i-1].size();j<lt;++j)
    			{
    				std::pair<int,int> pr=V[i-1][j];
    				int d=std::__gcd(now,pr.sd);
    				if(d!=now)V[i].push_back(std::make_pair(pr.ft,d)),now=d;
    			}
    		}
    		for(register int i=1;i<=m;++i)
    		{
    			int l,r;read(l);read(r);
    			query[r].push_back(std::make_pair(i,l));
    		}
    		for(register int i=1;i<=n;++i)
    		{
    			for(register int j=0,lt=V[i].size();j<lt;++j)
    			{
    				std::pair<int,int> pr=V[i][j];
    				if(M[pr.sd])T.add(M[pr.sd],-1);
    				T.add(pr.ft,1);M[pr.sd]=pr.ft;
    			}
    			for(register int j=0,lt=query[i].size();j<lt;++j)
    			{
    				std::pair<int,int> pr=query[i][j];
    				ans[pr.ft]=T.sum(i)-T.sum(pr.sd-1);
    			}
    		}
    		for(register int i=1;i<=m;++i)printf("%d
    ",ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    python从zk获取连接并测试dubbo接口
    利用python脚本和telnet调试dubbo接口
    python制造有序中文json串的方法
    unittest用pycharm执行报错
    安装jenkins时无法解析主机:www.jenkins.io
    mui 左右滑动效果
    mui 日期控件的用法
    sql 不同where下的统计
    使用EF关于分页查询时遇到的一点疑问
    css按钮定位在div底部
  • 原文地址:https://www.cnblogs.com/hongyj/p/9562843.html
Copyright © 2011-2022 走看看