首页 > 其他分享 >codeforces 264B B. Good Sequences(dp+数论)

codeforces 264B B. Good Sequences(dp+数论)

时间:2023-04-23 21:36:17浏览次数:52  
标签:prime Good temp int MAX ans codeforces Sequences dp


题目链接:

codeforces 264B


题目大意:

给出n个数,利用这n个数构造一个好的序列,好的序列是单调增的,而且序列中相邻的两个元素都不互质,问最长的好序列的长度是多少。


题目分析:

  • 首先我们定义状态dp[i]表示当前的数进行构造的序列末尾的数的质因数包含i的时候的最长的情况。
  • 然后我们从小到大枚举给出的每一个数,每次转移就是对于当前枚举的数,分解质因数,然后找到所有的dp[i](i为当前数的质因数中最大的),然后更新它所有的质因数i的dp[i]为前面找到的最大值加1,然后利用最后一个数更新后的dp[i]数组记录的就是利用所有给出的数得到的末尾的数包含i这个质因子时的最优答案,统计所有答案中最优的即可。

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 100007

using namespace std;

int a[MAX];
int dp[MAX];
int ans,n;
bool prime[MAX];

void init ( )
{
    memset ( prime , true , sizeof ( prime ) );
    prime[0] = prime[1] = false;
    for ( int i = 2 ; i*i < MAX ; i++ )
    {
        if ( !prime[i] ) continue;
        for ( int j = i*i ; j < MAX ; j += i )
            prime[j] = false;
    }
}


int main ( )
{
    init ( );
    while ( ~scanf ( "%d" , &n ) )
    {
        memset ( dp , 0, sizeof ( dp ) );
        for ( int i = 0 ; i < n ; i++ )
            scanf ( "%d" , &a[i] );
        ans = 0;
        if ( n == 1 )
        {
            puts ("1" );
            continue;
        }
        for ( int i = 0 ; i < n ; i++ )
        {
            int temp = 0;
            int x = a[i];
            for ( int j = 2 ; j*j <= x ; j++ )
            {
                if ( x%j ) continue;
                if ( !prime[j] ) continue;
                while ( x%j == 0 )
                    x /= j;
                temp = max ( temp , dp[j]+1 );
            }
            if ( x > 1 ) temp = max ( temp , dp[x]+1 );
            x = a[i];
            for ( int j = 2 ; j*j <= x ; j++ )
            {
                if ( x%j ) continue;
                if ( !prime[j] ) continue;
                while ( x%j == 0 )
                    x /= j;
                dp[j] = temp;
            }
            if ( x > 1 ) dp[x] = temp;
            ans = max ( temp , ans );
        }
        printf ( "%d\n" , ans );
    }
}


标签:prime,Good,temp,int,MAX,ans,codeforces,Sequences,dp
From: https://blog.51cto.com/u_7936627/6218748

相关文章

  • codeforces 159D D. Palindrome pairs( manacher+dp )
    题目链接:codeforces159D题目大意:给出一个字符出,求取这个字符串中互相不覆盖的两个回文子串的对数。题目分析:首先能够用manacher模板,因为这个算法处理的字符串的长度式奇数,所以我们首先将原字符串拓展,也就是用一个没有出现过的子串填充到每两个字符之间,首位也要添加,这样处理后得到......
  • codeforces 359B B. Permutation(简单构造)
    题目链接:codeforces359B题目大意:给出n和k,要求构造一个长度为2*n的排列,满足如下的式子:∑i=1n|a2∗i−1−a2∗i|−|∑i=1na2∗i−1−a2∗i|=2∗k题目分析:首先最终构造的2*k一定是小于n的偶数,如果我们直接放入自然数的排列,结果是0,我们将2*i-1和2*i分为一组,每次调换组内位置(每组只能......
  • codeforces 505B B. Mr. Kitayuta's Colorful Graph(bfs)
    题目链接:codeforces505B题目大意:给出一个有向图,边有不同的颜色,任意给出查询,查询两点能够只通过一种颜色连通的颜色的种类数。题目分析:根据不同颜色建边,bfs即可,队列维护可用的点。AC代码:#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<alg......
  • codeforces 332B B. Maximum Absurdity(rmq)
    题目链接:codeforces332B题目大意:给出一个序列,让找出不互相覆盖的两个长度为k的段,问在两个段的权值和最大的情况下,按照左边段的左端点排序,右边段的左端点作为第二关键字排序,得到的第一个答案。题目分析:很水的数据结构的题目,我们只需要先利用前缀和预处理出所有长度为k的段的总权值......
  • codeforces 234C C. Weather(枚举+前缀后缀预处理)
    题目链接:codeforces234C题目大意:给出一个序列,问最少修改多少个元素,能保证前半截全是负数,后半截全是正数。题目分析:预处理出前缀中大于等于0的数的个数和后缀中小于等于0的数的个数。枚举每一个位置,判断以当前位置为分界点时需要修改的元素的个数。AC代码:#include<iostream>#inc......
  • codeforces 172B B. Pseudorandom Sequence Period(暴力)
    题目链接:codeforces172B题目大意:给出生成元,和递推式,求一个有限群元素的个数题目分析:暴力求取循环节即可,因为元素个数不会超过mod的大小,所以暴力法复杂度仅仅是O(105)AC代码:#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cstdio>#de......
  • codeforces 368B B. Sereja and Suffixes(树状数组)
    题目链接:codeforces368B题目大意:给出一个长度为n的序列a,给出m个查询l,对于每个查询输出[l,n]的区间内不同数的个数。题目分析:将查询按照l的大小排序,从大到小的遍历,每次将>=当前l的位置的a[i]全部加入树状数组,树状数组记录每个数是否出现过。每次结果就是查询树状数组的总和,要保证......
  • codeforces 414B B. Mashmokh and ACM(dp)
    题目链接:codeforces414B题目大意:定义一个序列,前一项能够整除后一项,给定这个序列中数的取值范围和序列的长度,问有多少种构造方法。题目分析:我们定义状态dp[i][j]为前i项已经确定且第i项为j的方案数。转移方程dp[i][j]=∑k|jdp[i−1][k]复杂度O(n⋅k)AC代码:#include<iostream>......
  • codeforces 573B B. Bear and Blocks(线段树+dp)
    题目链接:codeforces573B题目大意:给出n个连续塔,每个塔有高度hi,每次取走最外层的块,问需要多少次操作能够拿光所有的块。题目分析:首先我们可以知道第一次操作时,对于每个塔的变化满足如下的公式:hi=min(hi−1,hi−1,hi+1)每次操作都满足如下的递推式,我们递推一下得到第k次操作第i......
  • codeforces 267A A. Subtractions(辗转相除)
    题目链接:codeforces267A题目大意:给出一个数对,(a,b)每次用较大的减较小的,直到出现0为止,问要进行多少次操作。题目分析:大的减小的操作,可以利用取模优化过程,也就是辗转相除,商是操作次数,余数是下一段与之前较小的数继续进行操作的数,水题不做赘述。AC代码:#include<iostream>#include......