首页 > 其他分享 >Educational Codeforces Round 120 (Rated for Div. 2) C,D

Educational Codeforces Round 120 (Rated for Div. 2) C,D

时间:2023-01-15 21:22:54浏览次数:66  
标签:Educational Rated int Codeforces long maxn 减法 include 我们

Educational Codeforces Round 120 (Rated for Div. 2) C,D

C

C

这个题目大意是给我们n个数,我们可以把ai变成ai-1,或者是把ai变成aj,而我们需要知道最少的操作数把n个数的和小于等于k

对于这些个操作,我们可以知道,我们先进行减法操作还是改变值的操作呢

当然是我们如果需要减法操作的话,我们就先对最小的那个进行减法,然后再把后面的若干个数变成那个后面的a1(如果有需要的话)

首先我们先遍历把后面多少个数变成a1,然后再讨论是否需要进行减法操作t

如果不考虑减法

now=sum[i]+(n-i)a[1],前i面个不变,i到n变成a1

如果now<=k t=0

否则,就需要判断需要几个减法操作

cha=k-now

对于这变化的n-i+1(还须包括a1),每多进行一个减法操作,cha就会减去(n-i+1)个,差值会减少,所以我们t就是cha除以n-i+1,向上取整

那么此时用过的操作数是

cnt=n-i+t

#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <cmath>
#define int long long 
using namespace std;
int n,k;
int t;
void solve()
{
    cin>>n>>k;
    vector<int>a(n+1,0);
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    vector<int>sum(n+1,0);
    sort(a.begin()+1,a.end());
    int ans=1e10;
    for (int i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]+a[i];
    }
    for (int i=1;i<=n;i++)
    {
        int t=0;
        if (sum[i]+(n-i)*a[1]<=k) t=0;
        else 
        {
            t=ceil((sum[i]+(n-i)*a[1]-k)*1.0/(n-i+1));
        }
        ans=min(ans,n-i+t);
    }
    cout<<ans<<'\n';
    return ;
}
signed main ()
{
    cin>>t;
    while (t--)
    {
        solve();
    }
    system ("pause");
    return 0;
}

D

D

这一个题大意是我们有一个长度为n的01串,我们可以对一段子串里面有k个1的子串对这些字符进行重排列,我们需要知道最后有多少种不同的排序

这一个是组合问题

我们首先要知道这k个1的跨度,这个跨度我们是这样判断的

以第一个1的位置作为最左边,以最右边是第k+1的前一个位置

如,对于k=2

011000001 那么此时第一段就是01100000

对于这一段里的重排列有多少不同的排列呢

当然是从这里面字符数量里面选出k个位置来放1(但是对于我们为什么没有减去原来的那一个排序呢,请往后看)

但是对于第i段和i+1段,会有重叠的部分(合集)

这个合集还是比较重要的

然后我们就只需要减去这个交集即可。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=3e5+10,mod=998244353;
#define int long long 
int inv[maxn],fac[maxn],ifac[maxn];
int n,k;
int pre[maxn],fix[maxn],pos[maxn];
string s;
void init()
{
    inv[1]=fac[0]=fac[1]=ifac[0]=ifac[1]=1;
    for (int i=2;i<=n;i++)
    {
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
        fac[i]=fac[i-1]*i%mod;
        ifac[i]=ifac[i-1]*inv[i]%mod;
    }
    return ;
}
int C(int m,int n)
{
    return fac[m]*ifac[n]%mod*ifac[m-n]%mod;
}
void solve()
{
    cin>>n>>k;
    cin>>s;
    init();
    s=" "+s;
    int last=1;
    int cnt=0;
    for (int i=1;i<=n;i++)
    {
        if (s[i]=='1')
        {
            pre[i]=last;//pre是上一1的后面一个位置,这个用于找最左端
            last=i+1;
            pos[++cnt]=i;
        }
    }
    last=n;
    for (int i=n;i>=1;i--)
    {
        if (s[i]=='1')//这个是找1后面一个1的前一个,用于找最右端
        {
            fix[i]=last;
            last=i-1;
        }
    }
    if (cnt<k||k==0)
    {
        cout<<1<<'\n';
        return ;
    }
    int res=0;
    for (int i=1;i+k-1<=cnt;i++)
    {
        int l=pre[pos[i]],r=fix[pos[i+k-1]];
        int l1=pre[pos[i+1]],r1=r;
        res+=C(r-l+1,k);
        if (i!=cnt-k+1)//和下一个k的重叠部分(交集)
        {
            res-=C(r1-l1+1,k-1);
        }
        res=(res+mod)%mod;
    }
    cout<<res<<'\n';
    return ;
}
signed main ()
{
    int t=1;
    while (t--)
    {
        solve();
    }
    system ("pause");
    return 0;
}

标签:Educational,Rated,int,Codeforces,long,maxn,减法,include,我们
From: https://www.cnblogs.com/righting/p/17054154.html

相关文章

  • Codeforces 732 Div2 A-D题解
    感觉做过这场啊,要不就是看过A题AquaMoonandTwoArrays问前加后减能不能把A变成B,首先这个貌似是经典老题了,无论怎么操作数列总和不变,如果和不相同,变不了,其他情况暴力判......
  • Educational Codeforces Round 119 (Rated for Div. 2)
    EducationalCodeforcesRound119(RatedforDiv.2)我真是越来越菜了,现在竟然连a都做不出来了,o(╥﹏╥)oAA这个题是对于每一个ai和ai+1,(an和a1)都有一个判断,判断这两......
  • Codeforces Round #843 (Div. 2)
    C.InterestingSequence(二进制)题目大意给定两个大于等于0的数\(n,\x\),求满足\(n\&(n+1)\&(n+2)\cdotsm=x\)的最小\(m\),若不存在输出-1。解题思路首先若\(n<x\)肯......
  • Educational Codeforces Round 108 (D记忆化搜索)
    D.MaximumSumofProducts题目大意:给定两个长度为n(n<=5000)的整型数组a,b可以对数组a进行至多一次以下操作:选择l,r并对l到r进行翻转求\(\sum\)a\(_i\)*b\(_i\)的......
  • Codeforces Round #839 F
    F.CopyofaCopyofaCopy题链我们发现这个操作是将中间不一样周围四个一样的形如1010101010变成全部都一样的显然这样变之后是不可还原的就是说这......
  • Codeforces Round #843 (Div. 2) A1A2BCE(D待补)
    url:Dashboard-CodeforcesRound#843(Div.2)-CodeforcesA1&&A2.GardenerandtheCapybaras题意:给你一个只由$a$和$b$两个字符组成的字符串现在要你把这个字......
  • Codeforces Round #834 (Div. 3) D. Make It Round(贪心/数论)
    https://codeforces.com/contest/1759/problem/D题目大意:给定一个数字n,要求扩大至多m倍,求最大的并且最多0的数字。input106115431354161005012345264......
  • Codeforces 1630 E Making It Bipartite 题解 (Dilworth定理)
    题目链接首先可以想到把题目中的那张图G建出来,由于要求这张图是二分图,把它复制一遍(\(G\toG'\)),然后对于每个u,连一条无向边\(u-u'\),这样就变成了最大独立集问题。但是一......
  • Codeforces 1630 E Making It Bipartite 题解 (Dilworth定理)
    题目链接首先可以想到把题目中的那张图G建出来,由于要求这张图是二分图,把它复制一遍(\(G\toG'\)),然后对于每个u,连一条无向边\(u-u'\),这样就变成了最大独立集问题。但是一......
  • 题解 CF678D【Iterated Linear Function】
    暴力解法。初学群论,可能写的不是很严谨,望大佬指正。problem\[g^{(n)}(x)=\begin{cases}x,&(n=0).\\f(g^{(n-1)}),&(n>0).\end{cases}\]其中\(f\)是一次函数。给出......