Codeforces Round #641 (Div. 2) A-C(B为DP,C为gcd预处理)

A: http://codeforces.com/contest/1350/problem/A

题意:f(n)+n,求第k次的结果。f(n)为n的最小公因数。

解析:模拟一下,就可以看出,这是一个d=2的等差数列,第一项是f(n)+n,求第k项。所以先把f(n)求出来。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int n , k ;
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        int a1;
        for(int i=2;i<=n;i++)
        {
            if(n%i==0)
            {
                a1=i;break;
            }
        }
        a1+=n;
        cout<<a1+(k-1)*2<<endl;
    }
}

 

B:http://codeforces.com/contest/1350/problem/B

题意:求最长递增序列。保证这个序列的相邻下标,后一个可以整除前一个。

解析:直接上最长递增序列的DP模板。但是要注意,第二层应该是for(int j=i+i;j<=n;j+=i),这样保证了相邻整除。比如i=1, j=2,3,4....更新了dp[2],那么用到dp[2]时,就需要dp[4]了。正好整除。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int dp[maxn];
ll a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)    
        {
            dp[i]=1;
            cin>>a[i];
        }
        int maxx=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+i;j<=n;j+=i)
            {
                if(a[i]<a[j])
                {
                    dp[j]=max(dp[j],dp[i]+1);
                    maxx=max(maxx,dp[j]);
                }
            }
        }
        cout<<maxx<<endl;
    }
}

 C:http://codeforces.com/contest/1350/problem/C

题意:求gcd{lcm{a1,a2....an}}

解析:根据题目的规则,有:

gcd1=gcd{lcm(a1,a2),lcm(a1,a3),lcm(a1,a4)......lcm(a1,an)}

每一项lcm都有a1,那么a1*x=gcd1,x就是a2....an的最大公约数了,x和a1的最小公倍数,就是整体的最大公约数了,所以可以写成:

gcd1=lcm(a1,gcd(a2....an))

同理,gcd2=lcm(a2,gcd(a3...an))

总的gcd=gcd(gcd1,gcd2,gcd3.......)

所以可以先后缀预处理一下a1~an的gcd,然后再从i=1开始每次:ans=gcd(ans,lcm(ai,f[i+1]))就可以了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
ll s[maxn],a[maxn];
ll getlcm(ll x,ll y)
{
    return x*y/__gcd(x,y);
}
int main()
{
    int n ;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=n;i>=1;i--)
        s[i]=__gcd(s[i+1],a[i]);
    ll ans=0;
    for(int i=1;i<=n;i++)
        {
            ans=__gcd(ans,getlcm(a[i],s[i+1]));
        }
    cout<<ans<<endl;
}

 

posted @ 2020-05-13 20:18  liyexin  阅读(169)  评论(0编辑  收藏  举报