程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu 4630 No Pain No Game

hdu 4630 No Pain No Game

編輯:C++入門知識

題意:給出一個n和1到n的某個排列,詢問q次,每次詢問[l,r]區間內任意挑兩個數,最大公約數的最大值是多少。

解題思路:記錄一個pre數組,pre[i]表示對於某個數i,已經出現過的它的倍數最近是在那個位置。將詢問按右端點排序。用樹狀數組維護從某一位置到maxn的最佳答案。從1到n開始掃描num[i],sqrt(num[i])的復雜度去枚舉它的約數x,那麼我們可以用這個x去更新所有pre[x]以前的答案(能更新則更新,後綴數組維護一個最大值)。假如我們現在處理到了第k個詢問的右端點是i,因為我們還只處理到了i,所以對於左端點一直到maxn的最大值即第k個詢問的答案。

 

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std ;

const int maxn = 55555 ;
struct Ans
{
	int l , r , ans ;
} p[maxn] ;

int c[maxn] , pre[maxn] ;

int lowbit ( int x ) { return x & ( -x ) ; }

void update ( int pos , int v )
{
	while ( pos > 0 )
	{
		c[pos] = max ( c[pos] , v ) ;
		pos -= lowbit ( pos ) ;
	}
}

int query ( int pos )
{
	int ret = 0 ;
	while ( pos < maxn - 10 )
	{
		ret = max ( ret , c[pos] ) ;
		pos += lowbit ( pos ) ;
	}
	return ret ;
}

bool cmp ( int i , int j )
{
	return p[i].r < p[j].r ;
}
int pos[maxn] , num[maxn] ;

int main ()
{
	int cas , n , i , j , m ;
	scanf ( "%d" , &cas ) ;
	while ( cas -- )
	{
		memset ( c , 0 , sizeof ( c ) ) ;
		memset ( pre , 0 , sizeof ( pre ) ) ;
		scanf ( "%d" , &n ) ;
		for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d" , &num[i] ) ;
		scanf ( "%d" , &m ) ;
		for ( i = 1 ; i <= m ; i ++ )
		{
			scanf ( "%d%d" , &p[i].l , &p[i].r ) ;
			pos[i] = i ;
		}
		sort ( pos + 1 , pos + m + 1 , cmp ) ;
		int tot = 1 ;
		for ( i = 1 ; i <= n ; i ++ )
		{
			if ( tot > m ) break ;
			for ( j = 1 ; j * j <= num[i] ; j ++ )
			{
				if ( num[i] % j ) continue ;
				if ( pre[j] != 0 ) update ( pre[j] , j ) ;
				pre[j] = i ;
				if ( j * j == num[i] ) continue ;
				int k = num[i] / j ;
				if ( pre[k] != 0 ) update ( pre[k] , k ) ;
				pre[k] = i ;
			}
			while ( tot <= m && p[pos[tot]].r == i )
			{
				p[pos[tot]].ans = query ( p[pos[tot]].l ) ;
				tot ++ ;
			}
		}
		for ( i = 1 ; i <= m ; i ++ )
		{
			if ( p[i].l == p[i].r )
			{
				puts ( "0" ) ;
				continue ;
			}
			printf ( "%d\n" , p[i].ans ) ;
		}
	}
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved