每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

Codeforces Round 856 (Div. 2)(C,D)

Codeforces Round 856 (Div. 2)(C,D)

C

C

这个题的大意就是给你n个非递减的数,然后我们对于一个数组,这个数组的价值是这样定义的

value=ai×ai+1...×aklen!

那么我们需要知道对于从ik这一段的数组的子数组,使得价值最大

对于这一价值的更大化,我们优先选择那些较大的,我们需要判断的就是此时的最小的是否是可以让价值变较大的,如果此时最小的数mi小于此时的长度,那么比起上一轮的最大价值value,此时的价值valuenow=value×anowlen,就变得比上一轮更小了,明显不划算

然后这个原来的数组就是一个非递减的数组,所以对于此时的最小值就是上一轮最优子序列的最前面一个数

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int maxn=2e5+10;
int t,n;
int a[maxn];
int ans[maxn];
void solve()
{
    cin>>n;
    int l=1;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        while (l<i&&a[l]<(i-l+1))
        {
            l++;
        }
        ans[i]=max(1,i-l+1);
    }
    for (int i=1;i<=n;i++)
    {
        cout<<ans[i]<<" ";
    }
    cout<<'\n';
    return ;
}
signed main ()
{
    cin>>t;
    while (t--)
    {
        solve();
    }
    system ("pause");
    return 0;
}

D

D

这个题的大意就是给你2n个数,然后我们需要知道这2n个数可以组成多少个数

这个组成方式是以质数的幂次相乘的形式组成的,如,此时有一个m

m=p1e1×p2e2×...×pnen

以上面的这种形式

一个一个构造显然是不太行的

所以我们可以对于每一个piei一个一个单独来看

对于第ipiei的不同组成,从而得知最后得到的m有多少种

那么对于每一个数x,有y个,那么求dp[i]选择i个底数,并且我们已经把sum个数的位置已经安排好了

假如x是作为幂次的,那么我们可以从剩余的幂次位置还有nsumi)个,我们从这些位置中选择y个位置分配

假如x可以作为底数,那么我们从这y个里面拿出一个作为第i个底数,然后其他的y1个需要从剩余的幂次位置(n(sum(i1))中选择

由于每个质数都只能作为底数最多一次,所以,对于同样的数,分配在不同的位置,那么对于每一个质数都是不同的效果,那么最后的值都是不一样的,因为质数是不可以由其他数转换而来的,这就是为什么要通过每一个数的位置分配来计算m的数量

然后具体的就看代码吧

#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
const int maxn=4044+10;
const int N=1e6+10;
const int mod=998244353;
#define int long long 
int t,n;
int a[maxn];
int f[maxn],invf[maxn];
bool is[N];
int p[N],cnt;
int dp[maxn];
int ksm(int x,int p)
{
    int res=1;
    while (p)
    {
        if (p&1)
        {
            res=(res*x)%mod;
        }
        x=(x*x)%mod;
        p>>=1;
    }
    return res%mod;
}
void init()
{
    int mx=4044;
    f[0]=f[1]=1;
    for (int i=2;i<=mx;i++)
    {
        f[i]=f[i-1]*i%mod;
    }
    invf[mx]=ksm(f[mx],mod-2);
    for (int i=mx-1;i>=0;i--)
    {
        invf[i]=1ll*invf[i+1]*(i+1ll)%mod;
    }
    return ;
}
int C(int n,int m)
{
    if (n==m&&m==-1) return 1;
    if (n<0||m<0) return 0;
    return f[n]*invf[n-m]%mod*invf[m]%mod;
}
void prime()
{
    for (int i=2;i<N;i++)
    {
        if (!is[i]) p[++cnt]=i;
        for (int j=1;j<=cnt&&i*p[j]<N;j++)
        {
            is[i*p[j]]=true;
            if (i%p[j]==0) break;
        }
    }
    is[1]=true;//!is[x]代表x是质数,1不是质数
    return ;
}
void solve()
{
    cin>>n;
    map<int,int>cnt;
    for (int i=1;i<=2*n;i++)
    {
        cin>>a[i];
        cnt[a[i]]++;
    }
    int sum=0;
    vector<int>dp(n+1,0);
    dp[0]=1;
    for (auto [x,y]:cnt)
    {
        vector<int>ndp(n+1,0);
        for (int i=0;i<=n;i++)
        {
            ndp[i]=(ndp[i]+dp[i]*C(n-(sum-i),y)%mod)%mod;
            if (i>=1&&!is[x])
            {
                ndp[i]=(ndp[i]+dp[i-1]*C(n-(sum-(i-1)),y-1)%mod)%mod;
            }
        }
        sum+=y;
        dp=ndp;
    }
    cout<<dp[n]<<'\n';
    return ;
}
signed main ()
{
    t=1;
    init();
    prime();
    while (t--)
    {
        solve();
    }
    system ("pause");
    return 0;
}
posted @   righting  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示