Codeforces Round #641 (Div. 2)-A,B,C,D

codeforces-1350-A. Orac and Factors

题意:定义f(n)是n的最小非平凡因子,也就是除了1,n之外的最小因子
给出两个正整数n,k你需要进行 k次操作,每次将 n加上 f(n)
n为偶数的话其最小因子一定是2,直接输出n+2*k,n为奇数n+最小因子就一定是偶数了,输出n+最小因子+2*(n-1)
比赛时智商掉线了,写的巨麻烦hhhhh

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 1e6+9;

inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}

int _;
//==================================================================
ll a[maxn];
//==================================================================

int main()
{
    // freopen("in.in", "r", stdin);
    for(int i=2;i<=1000000;i++)
    {
        for(int j=2;j<=sqrt(i);j++)
        {
            if(i%j==0)
            {
                a[i]=j;
                break;
            }
        }
        if(a[i]==0) a[i]=i;
    }
    // for(int i=1;i<=10;i++) printf("%lld ",a[i]);
    for(scanf("%d",&_);_;_--)
    {
         ll n,k;
         scanf("%lld%lld",&n,&k);
         ll x=n;
         for(int i=1;i<=k;i++)
         {
             ll y=a[x]+x;
             x=y;
             if(y%2==0)
             {
                 x=x+((k-i)*2);
                 break;
             }
         }
         printf("%lld\n",x);
    }
    return 0;
}

codeforces-1350-B. Orac and Models

题意:在满足下标成倍数增长的情况下,找到最长的上升序列的长度
一个暴力的dp
对于每一个数a[i],枚举他的因子满足条件的dp[i_]的最大值max_,dp[i]=max_+1

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 2e5+9;

inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}

int _;
//==================================================================
int a[maxn],dp[maxn];
//==================================================================
int main()
{
    // freopen("in.in","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        clean(dp,0);
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        dp[1]=1;
        for(int i=2;i<=n;i++)
        {
            int max_=0;
            for(int j=1;j<=sqrt(i);j++)
            {
                if(i%j==0&&a[i]>a[j]) 
                {
                    max_=max(max_,dp[j]);
                }
               if(i%j==0&&a[i]>a[i/j])
                {
                    max_=max(max_,dp[i/j]);
                }
            }
                dp[i]=max_+1;
        }
        int maxx=1;
        for(int i=1;i<=n;i++) maxx=max(maxx,dp[i]);
        printf("%d\n",maxx);
    }
    return 0;
}

codeforces-1350-C. Orac and LCM

题意:给你一个数组,求他们两两相求的最小公倍数形成的新数组的最大公约数
我的做法稍微麻烦了一点
我们知道对于任意一个数都有,为一个质数
每两个数的lcm就是,因为我们对p11和p12取了个最大值,所以序列中prime[i]这个质数的最小的p被整没了,后续我们再求最大公约数的时候prime[i]的那个p就应该是第二小的p
所以!开个vector[maxn] 对每一个数进行质因子分解,将分解后质因子的幂次存于对应质因子的vector中,如果vector[i]的长度为n,那么我们找vector中第二小的,如果为n-1,那最小是0但我们没有放进vector,所以我们取vector中最小的,如果小于n-1,那第二小的我们没有放进vector,就是0
最后遍历所有质数,乘一下就好啦~
我可能是个憨憨,当p=0时也放进vector了,然后妥妥MLE…… ╰(艹皿艹 )

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 2e5+9;

inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}

int _;
//==================================================================
vector<int>ve;
vector<int>cnt[200000];
int a[maxn];
ll fpow(ll a,ll b,ll c)
{
    a%=c;
    ll ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%c;
        a=a*a%c;
        b>>=1;
    }
    return ans%c;
}
//==================================================================
int main()
{
    // freopen("in.in","r",stdin);
    for(int i=2;i<=200000;i++)
    {
        int flag=0;
        for(int j=2;j<=sqrt(i);j++)
        {
            if(i%j==0)
            {
                flag=1;
                break;
            }
        }
        if(!flag) ve.push_back(i);
    }
    int n,maxx=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
		int x=a[i];
		for(int j=0;j<=x;j++)
		{
			int cnt_=0;
			if(ve[j]>sqrt(x)) break;
			if(x%ve[j]!=0) continue;
            while(x%ve[j]==0)
            {
                cnt_++;
                x/=ve[j];
            }
			cnt[ve[j]].push_back(cnt_);
		}
		if(x>1) cnt[x].push_back(1);
    }

    ll ans=1;
    for(int i=0;i<=17984;i++)
    {
        sort(cnt[ve[i]].begin(),cnt[ve[i]].end());
	if(cnt[ve[i]].size()==n) ans*=fpow(ve[i],cnt[ve[i]][1],mod);
	else if(cnt[ve[i]].size()==n-1) ans*=fpow(ve[i],cnt[ve[i]][0],mod);
    }
    printf("%lld\n",ans);
    return 0;
}

codeforces-1350-D. Orac and Medians

题意:给你一组数,每次你可以选择一段数变成他的中位数,问整个序列中的数能不能都变成k。可以变化很多次

心态崩了

理解了挺长时间,搬一位大佬的解法

这道题有一个转换,就是其实只有 3 种数,大于 k,小于 k 和等于 k,我们分别转换为 2,0,1。我们要把所有区间化为 1。
如果这个序列没有 1,那么答案肯定是no。
然后我们可以发现,2 的影响不大,因为一旦 1 和 2 相邻,那么合并一下一定是 1。但是 0 的影响就很大。对于一个长度为 len 的区间,一旦中位数是 0 那么这个区间就是 0,所以我们要判断是不是所有区间的中位数都是 0。
我们化简亿下这个条件。一旦一个区间是可以化成 1 的,那么一定存在一个长度为 3 的区间是可以化成 1 的;如果所有区间都不可以,那么所有长度为 3 的也都不可以。所以我们只需要判断长度为 3 的即可。存在这样的区间,就是存在一个长度为 3 的区间使得里面 0 的个数不大于 1。

代码:


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a)&-(a))
#define clean(a,b) memset(a,b,sizeof(a))
const int mod = 1e9 + 7;
const int inf=0x3f3f3f3f;
const int maxn = 2e5+9;

inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}

int _;
//==================================================================
int a[maxn],b[maxn];
//==================================================================
int main()
{
    // freopen("in.in","r",stdin);
	for(scanf("%d",&_);_;_--)
	{
		int n,k,flag1=0;
		scanf("%d%d",&n,&k);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			if(a[i]==k) b[i]=1,flag1++;
			else if(a[i]<k) b[i]=0;
			else b[i]=2;
		}
		int flag=0;
		for(int i=1;i<=n-2;i++)
		{
			int cnt=0;
			for(int j=0;j<=2;j++)
			{
				if(b[i+j]==0) cnt++;
			}
			// printf("%d\n",cnt);
			if(cnt<2) flag=1;
		}

		if(n==2)
		{
			if(b[1]==1&&b[2]==0||b[1]==0&&b[2]==1) flag=0;
			else flag=1;
		}
		if(flag1==0) flag=0;
		if(flag1==n) flag=1;
		if(flag) puts("yes");
		else puts("no");
		}
    return 0;
}
posted @ 2020-05-16 14:57  L·S·D  阅读(125)  评论(0编辑  收藏  举报