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;
    }
    
  • 相关阅读:
    linux嵌入式系统交叉开发环境
    Codeforces Round #208 E. Dima and Kicks
    mvn 编译错误java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter. <init>(Z)V
    黑马程序员_<<TCP>>
    微信/易信公共平台开发(四):公众号调试器 (仿真微信平台,提供PHP源码)
    用pdb调试OpenStack Havana
    MySql Odbc等驱动下载地址分享下
    导入exce表格中的数据l到数据库
    关闭数据备份信息写入数据库日志
    SQL Server之RAID简介
  • 原文地址:https://www.cnblogs.com/hongyj/p/9562843.html
Copyright © 2011-2022 走看看