codeforces959D 2000分数学

题目传送门

题意:

给你 \dpi{150}n 个数的序列,第 \dpi{150}i 个数是 \dpi{150} a_i 。

让你生成一个 \dpi{150}n 个数的 \dpi{150} b 序列。

\dpi{150} b 序列的要求:

(1)字典序大于等于 a 序列。

(2)两两互质。即 gcd(b_i,b_j)=1 (i \neq j) 。

题解:

通过素数筛的思路去解这道题。

从左往右生成 \dpi{150} b 序列,构造 b_i 的方法如下:

\dpi{150} b 序列的前 i-1 个数包括的质因子的倍数已经筛过了。

如果前 i-1 个数已经产生过大于对应位置的 a 序列的数,那么 b_i 不受 a_i 的限制。否则需满足 b_i \geqslant a_i 。

然后找到最小的合法的未被筛过的数即可。

注意路径压缩。

扫描二维码关注公众号,回复: 9153225 查看本文章

我写的递归的路径压缩会MLE,用非递归的路径压缩过的。

感受:

逐梦演艺圈!

一直MLE或TLE的感觉真是妙不可言。

这道题想了几分钟就会了。

然后开始MLE。我想1e6都开不了吗?

那我改成1e5总可以吧。

试了几发,可能是路径压缩递归的问题?

改成非递归,终于不MLE了。

开始TLE。

非递归写的有问题,这不是没有起到路径压缩的作用吗? 

AC!

代码:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 3e6 + 5 ;
const int maxm = 1e6 + 5 ;
int n , a[maxm] ;
int cnt = 0 ;
bool vis[maxn] ;
int prime[maxm] ;
int nxt[maxn] ;
bool flag = 0 ;
void get_prime()
{
	memset(vis , 0 , sizeof(vis)) ;
	vis[1] = 1 ;
    for(int i = 2 ; i <= maxn - 5 ; i ++)
	{
        if(!vis[i]) 
		   prime[++ cnt] = i ;
        for(int j = 1 ; j <= cnt && i * prime[j] <= maxn - 5 ; j ++)
		{
            vis[i * prime[j]] = 1 ;
            if(i % prime[j] == 0) break ;
        }
    }
}
int find(int u) 
{
	int temp = 0 ;
	int y ;
    for(int i = u ; ; i = nxt[i])  if(nxt[i] == i){temp = i ; break ;}
    for(int i = u ; i <= temp ; i = y)  y = nxt[i] , nxt[i] = temp + 1 ;
    return temp ;
}
void cal(int x)
{
	for(int i = x ; i <= maxn - 5 ; i += x)  
	  if(nxt[i] == i)  nxt[i] = i + 1 ;
}
void solve(int x , int id)
{
	int y = find(x) ;
	if(!flag && y > a[id])  flag = 1 ;
	nxt[y] = y + 1 ;
	printf("%d " , y) ;
	for(int i = 1 ; i <= cnt && prime[i] * prime[i] <= y ; i ++)
	{
		if(y % prime[i] == 0)
		{
			cal(prime[i]) ;
			while(y % prime[i] == 0)  y /= prime[i] ;
		}
	}
	if(y > 1)  cal(y) ;
}
int main()
{
	scanf("%d" , &n) ;
	for(int i = 1 ; i <= n ; i ++)  scanf("%d" , &a[i]) ;
	get_prime() ;
	for(int i = 1 ; i <= maxn - 5 ; i ++)  nxt[i] = i ;
	for(int i = 1 ; i <= n ; i ++)
	   if(!flag) solve(a[i] , i) ;
	   else  solve(2 , i) ;
	printf("\n") ;
	return 0 ;
}

发布了215 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Irving0323/article/details/104102340
今日推荐