Codeforces Global Round 7【ABCD】(题解)

目录

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

    • 比赛链接:传送门

      • D题只有数据范围的区别,故只写D2。
      • 好多题啊,随缘更新。(其实懒得写)
    • A - Bad Ugly Numbers
    • B - Maximums
    • C - Permutation Partitions
    • D2 - Prefix-Suffix Palindrome (Hard version)

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

比赛链接:传送门

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\n";
            continue;
        }
        else{
            cout<<2;
            for(int i=1;i<n;i++)cout<<3;
            cout<<"\n";
        }
    }
    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\)块,求每块的最大值之和。形式上为\(\sum\limits_{i=1}^{k} {\max\limits_{l_i \leq j \leq r_i} {p_j}}\),并算出有多少种分法可以达到这个最大值。
题解: 最大值就是\([n-k+1,n]\)的区间和。根据这\(k\)个数来划分区间即可,记录这\(k\)个数的下标,分法总数为\(\displaystyle\prod_{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<<"\n";
    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<<"\n";
            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<<"\n";
            if(pl>pr)continue;
            if(pl<=l){
                int nl=pr,nr=s.length()-pl;
                //cout<<"1:"<<nl<<" "<<nr<<"\n";
                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<<"\n";
                if(nl+1+s.length()-nr>=anslen&&nl<nr)
                    anslen=nl+1+s.length()-nr,ansl=nl,ansr=nr;
            }
        }
        //cout<<ansl<<" "<<ansr<<"\n";
        string ans=s.substr(0,ansl+1)+s.substr(ansr);
        cout<<ans<<"\n";
    }
    return 0;
}

原文地址:https://www.cnblogs.com/charles1999/p/12531391.html

时间: 2024-08-30 07:01:16

Codeforces Global Round 7【ABCD】(题解)的相关文章

Codeforces Global Round 1 (A-E题解)

Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^(k-1)+a2*b^(k-2)+...+ak*b^0的奇偶性. 题解: 暴力求模2意义下的值就好了. 代码如下: #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5+5; int

Codeforces Global Round 5 部分题解

tourist的劲题,掉了17分,着实心痛,本来是有分可恰到的 A.给你一个数列\(a\),你需要构造一个数列\(b\),使得每一个\(b\)都等于\(a/2\),向上或向下取整由你决定 并且还要使得\(\sigma b\)的总和等于0 数据是保证有解的 那么我们就令所有\(b\)等于\(\lfloor a/2 \rfloor\),求出总和 再遍历一遍数组,sum过大则把某些负数调整为向上取整,否则把正数调整 代码: #include <bits/stdc++.h> #define int l

【手抖康复训练1 】Codeforces Global Round 6

[手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思路手抖过不了样例,C题秒出思路手抖过不了样例*3 D题 手抖 过的了样例 ,调了1h,赛后发现变量名写错了,改一个字符就能AC... 题目等补完题一起放上来QAQ 原文地址:https://www.cnblogs.com/ttttttttrx/p/12110199.html

codeforces global round 1题解搬运

A,B很简单,跳过了. C题规律相当明显,可以直接对\(2^n-1\)打表,也可以不打表直接算最大因数. D题两种操作转化一下DP即可. E题考虑查分数组不变的性质. F题考虑dfs时动态维护每个叶子的深度,从一个节点走向它的孩子相当于孩子对应的区间加,不包含孩子的区间减. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int P=1050000; const int N=500010; in

Codeforces Global Round 3 题解

A 送分题 B 送分题 C 考虑先依次把\(2\sim n-1\)换到正确的位置,这个只要利用\(1,n\)两个位置交换就行了. 然后如果\(n\)在第一位就交换\(1,n\). D 显然\(a<b\)和\(a>b\)的可以分别考虑.不失一般性考虑\(a<b\)的.那么相当于要选出若干二元组并排序,要求满足\(b_i>a_{i+1}\).考虑对数值建点,\(a\)向\(b\)连边,所有\(i\)向\(i-1\)连边,相当于要走一条路径经过最多\(a->b\)的边.这样可以直观

Codeforces Global Round 4 题解

技不如人,肝败吓疯…… 开场差点被 A 题意杀了,幸好仔细再仔细看,终于在第 7 分钟过掉了. 跟榜.wtf 怎么一群人跳题/倒序开题? 立刻紧张,把 BC 迅速切掉,翻到了 100+. 开 D.感觉有点吓人……感觉有点可做? 的确挺可做.再切掉 D,但是此时已经到 300+ 了. 没事,还能翻. 开 E.这……什么玩意? 瞄了一眼 F1,…… 盯着这两题盯到自闭. 最后 rk 1000 左右.我的名字颜色真的是对的吗…… A 看懂题了就是水题.选上所有小于等于第一个党派一半人数的党派,如果不行

Educational Codeforces Round 75 ABCD题解

A. Broken Keyboard Description 给出一串小写字母字符序列,连续出现两次的字母为坏掉的,按字典序输出所有没有坏掉的字母. Solution 模拟暴力删除字母,注意相同字母的去重. 1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cst

Codeforces Global Round 7 题解

A 一种合法构造方式是\(299\cdots 9\) code B 发现每次的\(x_{i-1}\)都是知道的,于是可以直接递推. code C 最终答案所选的数一定是\(n-k+1\)到\(n\)的所有数.把这些数所在的位置记作\(p_1,p_2,\cdots,p_k\). 不难发现每个\(r_i\in [p_i,p_{i+1})\),于是答案就是\(\prod (p_{i+1}-p_i)\). code D 首先把首尾能构成回文的部分删掉,因为这部分一定会出现在答案中. 问题变成了在当前字符

【 Codeforces Global Round 1 B】Tape

[链接] 我是链接,点我呀:) [题意] x轴上有m个连续的点,从1标号到m. 其中有n个点是特殊点. 让你用k段区间将这n个点覆盖. 要求区间的总长度最小. [题解] 一开始假设我们需要n个胶带(即包含每一个点) 然后因为k<=n 所以可能胶带不够用. 那么就得一个胶带跨过两个点. 怎么选择最好呢? 可以把b[i]-b[i-1]-1处理出来排个序. (优先取较小的花费) 然后取前n-k个累加和sum. 因为每取一个就少用一段胶带. 然后sum+n就是答案了 [代码] import java.i