Codeforces Round #737 (Div. 2)部分题解

A

点击此处查看对应的题目.
  这题要求将一个序列分为a与b两个序列,求出 ( f ( a ) + f ( b ) ) m a x (f(a)+f(b))_{max} (f(a)+f(b))max,所以我们只要分出一个最大值成为序列 f ( a ) f(a) f(a),再写出 f ( b ) f(b) f(b)的表示相加就是答案,最后记得保留九位小数。

时间复杂度 O ( n ) O(n) O(n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10,INF=1e9;
int a[N];

void solve()
{
    int n;
    cin>>n;

    for(int i=0;i<n;i++) cin>>a[i];
    int maxn=-INF;ll sum=0;

    for(int i=0;i<n;i++) {
        maxn=max(maxn,a[i]);
        sum+=a[i];
    }
    sum-=maxn;

    printf("%.9lf\n",(double)((double)sum/(n-1)+maxn));
}
int main()
{
    int t;
    cin>>t;

    while(t--){
        solve();
    }
    return 0;

}

B

点击此处查看对应的题目.
  本题涉及算法:二分+排序
  本题我一度交了两次WA:第一次WA是我以为只要判断出现递减区间的次数与k的关系就可以出结论,但后来发现即便出现递减区间的次数小于等于k也有可能出现序列中的其他元素大小在该递减区间中间从而无法排序,所以不能仅仅用递减区间的次数与k比较,应该用子序列的个数,即统计子序列的个数cnt。

  第二次WA是因为我忽略了即便出现以上状况也不至于无法排序,只要k足够大就不影响,只需要将子序列数量值++即可

  解题思路:先判断子序列数量与k的关系,如果k够用,则继续判断是否出现序列中的其他元素大小在该递增区间中间的情况,有则子序列数量值++。最后再次进行第一步的判断。

时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10,INF=1e9;
int a[N],t[N];

void solve()
{
    int n,k;
    cin>>n>>k;

    int cnt=1;
    for(int i=0;i<n;i++) cin>>a[i];
    t[0]=a[0];
    if(n==k) {puts("Yes");return;}

    for(int i=1;i<n;i++){
        if(a[i] < a[i-1]) cnt++;
        t[i]=a[i];
    }
    sort(t,t+n);
  
    if(cnt > k) puts("No");
    else {
        for(int i=1;i<n;i++){
            if(a[i] > a[i-1]){
                int j=upper_bound(t,t+n,a[i-1])-t;
                if(t[j] < a[i]) cnt++;
            }
        }
        if(cnt > k) puts("No");
        else puts("Yes");
    }
}
int main()
{
    int t;
    cin>>t;

    while(t--){
        solve();
    }

    return 0;
}

C

点击此处查看对应的题目.
  本题涉及算法:快速幂+组合数学

我们规定,左式是&,右式是^,想要满足本题条件,做事必须大于等于右式。本题涉及位运算的知识,主要是看n是偶数还是奇数。

if(如果n是奇数),考虑两种情况:

 左式为0 :此时右式为0。n为奇数(左式为0),在n个里面选偶数个为1,得到异或结果为0
C n 0 + C n 2 + C n 4 + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + C n n − 1 = 2 n − 1 C^{0}_{n}+C^{2}_{n}+C^{4}_{n}+······+C^{n-1}_{n}=2^{n-1} Cn0+Cn2+Cn4++Cnn1=2n1

 左式为1:此时右式为1。只有一种情况,就是序列全为1(左式为1)

两种情况相加得: 2 n − 1 + 1 2^{n-1}+1 2n1+1(注意)

else if(如果n是偶数),考虑两种情况:

 左式等于右式 :n为偶数(左式为0),在n个里面选偶数个为1,得到异或结果为0,全选的话左式大于右式
C n 0 + C n 2 + C n 4 + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + C n n − 2 = 2 n − 1 − C n n C^{0}_{n}+C^{2}_{n}+C^{4}_{n}+······+C^{n-2}_{n}=2^{n-1}-C^{n}_{n} Cn0+Cn2+Cn4++Cnn2=2n1Cnn(注意)

 左式大于右式:固定前i个(前i个数相等),并让第i个为1,i后面的随便选
( ∑ i = 1 k ( 2 n − 1 − 1 ) i − 1 ∗ ( 2 n ) k − i \sum^{k}_{i=1}(2^{n-1}-1)^{i-1}*(2^n)^{k-i} i=1k(2n11)i1(2n)ki)

时间复杂度 O ( n ( l o g n ) 2 ) O(n(logn)^2) O(n(logn)2)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10,INF=1e9,mod=1e9+7;
int a[N];

ll qmi(int a,int b,int p)
{
    ll res = 1 % p;
    while(b){
        if(b & 1) res = res * a % p;
        a = (ll)a * a % p;
        b >>= 1;
    }
    return res;
}
void solve()
{
    ll res=0;
    int n,k;
    cin >> n >> k;
    if(k == 0) {cout << 1 <<'\n'; return;}

    if(n & 1) res = qmi((qmi(2,n - 1,mod) + 1),k,mod);
    else {
        for(int i = 1;i <= k;i ++){
             res += qmi(qmi(2,n-1,mod)-1,i-1,mod)*qmi(qmi(2,n,mod),k-i,mod)%mod;
        }
        ll another_case = qmi(qmi(2,n - 1,mod) - 1,k,mod);
        res = (res + another_case) % mod;
    }
    cout << res <<'\n';
}
int main()
{
    int t;
    cin>>t;

    while(t--){
        solve();
    }

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

marvel121

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值