Codeforces Global Round 7ABCD(题解)

Posted charles1999

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Global Round 7ABCD(题解)相关的知识,希望对你有一定的参考价值。


涵盖知识点:思维、构造、马拉车。

比赛链接:传送门

D题只有数据范围的区别,故只写D2。

好多题啊,随缘更新。(其实懒得写)

A - Bad Ugly Numbers

题意: 构造一个长度为(n)的数字使得其不能被其中的每一位数整除。
题解: 2333333(雾)
Accept Code:

#include <bits/stdc++.h>
using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        if(n==1){
            cout<<"-1
";
            continue;
        }
        else{
            cout<<2;
            for(int i=1;i<n;i++)cout<<3;
            cout<<"
";
        }
    }
    return 0;
}

B - Maximums

题意: 对于数组(a),数组(x)满足(x_i = max(0, a_1, ldots, a_{i-1}),x_1=0),数组(b)满足(b_i = a_i - x_i)。现在给定(b),要求反推(a)
题解: 顺着算一遍维护一下最大值加一下就好了。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
typedef long long ll;
ll a[maxn];
int main(){
    int n;
    cin>>n;
    ll x=0;
    for(int i=0;i<n;i++){
        cin>>a[i];
        a[i]+=x;
        x=max(x,a[i]);
        cout<<a[i]<<" ";
    }
    return 0;
}

C - Permutation Partitions

题意: 给定一种([1,n])的排列,现在让你分成(k)块,求每块的最大值之和。形式上为(sumlimits_{i=1}^{k} {maxlimits_{l_i leq j leq r_i} {p_j}}),并算出有多少种分法可以达到这个最大值。
题解: 最大值就是([n-k+1,n])的区间和。根据这(k)个数来划分区间即可,记录这(k)个数的下标,分法总数为(displaystyleprod_{i=1}^{k-1}(idx_{i+1}-idx_{i}))
Accept Code:

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10,mod=998244353;
typedef long long ll;
int main(){
    int n,k;
    cin>>n>>k;
    ll ans=1,sum=0,l=0;
    for(int i=1,p;i<=n;i++){
        cin>>p;
        if(p>n-k){
            sum+=p;
            if(l)
                ans=ans*(i-l)%mod;
            l=i;
        }
    }
    cout<<sum<<" "<<ans<<"
";
    return 0;
}

D2 - Prefix-Suffix Palindrome (Hard version)

题意: 给定串(s),从(s)的前缀和后缀取任意长度进行拼接成新串(t),使得(t)为回文串并尽可能长。
题解: 先双端扫描一遍,确定回文的前缀和后缀,获得左区间和右区间。然后再依次扫描每一个字母为中心的回文串,若回文串左端探入左区间或者右端探入右区间,判断并更新答案。D1可以应该可以暴力判回文,D2利用马拉车获得的(len)数组优化计算一下就可以了。具体计算看代码实现。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
string s,t;
int len[maxn<<1];
void manacher(){
    int center,right=0,radius;
    for(int i=1;i<t.length()-1;i++){
        if(i>=right)radius=1;
        else radius=min(right-i+1,len[center*2-i]);
        while(t[i+radius]==t[i-radius])radius++;
        if(i+radius-1>right)right=i+radius-1,center=i;
        len[i]=radius;
    }
}
int main(){
    int cas;
    cin>>cas;
    while(cas--){
        cin>>s;
        t="@#";
        for(char i:s){
            t+=i;
            t+='#';
        }
        t+='$';
        manacher();
        int l=0;
        while(l<s.length()&&s[l]==s[s.length()-l-1])l++;
        if(l>=s.length()){
            cout<<s<<"
";
            continue;
        }
        int anslen=0,ansl=0,ansr=0;
        for(int i=2;i<=t.length()-3;i++){
            int pl=(i-len[i])>>1,pr=(i+len[i]-4)>>1;
            //cout<<pl<<" "<<pr<<"
";
            if(pl>pr)continue;
            if(pl<=l){
                int nl=pr,nr=s.length()-pl;
                //cout<<"1:"<<nl<<" "<<nr<<"
";
                if(nl+1+s.length()-pl>=anslen&&nl<nr)
                    anslen=nl+1+s.length()-nr,ansl=nl,ansr=nr;
            }
            if(pr>=s.length()-l-1){
                int nr=pl,nl=s.length()-pr-2;
                //cout<<"2:"<<nl<<" "<<nr<<"
";
                if(nl+1+s.length()-nr>=anslen&&nl<nr)
                    anslen=nl+1+s.length()-nr,ansl=nl,ansr=nr;
            }
        }
        //cout<<ansl<<" "<<ansr<<"
";
        string ans=s.substr(0,ansl+1)+s.substr(ansr);
        cout<<ans<<"
";
    }
    return 0;
}

以上是关于Codeforces Global Round 7ABCD(题解)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Global Round 7 题解(未完)(ABCD)

Codeforces Global Round 7 总结

Codeforces Global Round 7

Codeforces Global Round 7 题解

Codeforces Global Round 7 D2. Prefix-Suffix Palindrome (Hard version) -- manacher

Codeforces Global Round 7 D2. Prefix-Suffix Palindrome (Hard version)(Manacher算法+输出回文字符串)