首页 > 其他分享 >【补题】2023河南省赛

【补题】2023河南省赛

时间:2023-05-17 23:44:30浏览次数:59  
标签:log 河南省 复杂度 int maxn 补题 2023 include define

题目链接

https://codeforces.com/gym/104354

A. 小水獭游河南

签到题。

初看有点吓人,跟回文串有关,会不会是PAM啥的,然后是大水题。。。

容易发现A串的约束非常强,没有重复字符,意味着A串的长度最大也就是26。我们枚举A串,同时看剩余的后缀是不是回文串就行了。

时间复杂度\(\Theta(26n)\)

代码:

点击查看代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define maxn 100010
using namespace std;
char s[maxn];
int c[26];
int check(int l,int r){
    int flag=1,i,j;
    for(i=l,j=r;i<=j;++i,--j){
        if(s[i]!=s[j]){
            flag=0;
            break;
        }
    }
    return flag;
}
int main(){
    int i,j,n,T,flag,k;
    char last;
    // freopen("test.in","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%s",s);
        flag=0;
        for(i=0;i<26;++i) c[i]=0;
        n=strlen(s);
        last=s[n-1];
        for(i=0;i<n;++i){
            if(i>0&&s[i]==last){
                if(check(i,n-1)){
                    flag=1;break;
                }
            }
            c[s[i]-'a']++;
            if(c[s[i]-'a']>1) break;
        }
        if(flag) printf("HE\n");
        else printf("NaN\n");
    }
    return 0;
}

B. Art for Rest

实现很简单,但是感觉还是难以一眼看出做法,不知道为啥过的人这么多。

考虑暴力,我们直接枚举块长,然后对于已经分好块的数组,检验是否满足条件。

当然模拟排序过程是不可取的,我们不如考虑什么情况下不可能满足条件。

简单思考一下发现,块必须是块间“整体有序”的,也就是说,如果我们一个一个块扫过去,不能出现当前块中某个值比前面块中某个值小的情况。

然后我们只要维护前缀最大值,查询区间最小值,比较即可。

由于数据较大,推荐使用\(O(1)\) 查询的ST表实现RMQ。

等等,你外面不还有一层循环吗,总共两层循环复杂度珂以接受吗?

注意到我们内层循环的次数是\(\lfloor \frac{n}{k}\rfloor\)的,根据调和级数求和的结论知:最终复杂度是\(\Theta(n log n)\)的。

代码:

点击查看代码
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define maxn 1000010
using namespace std;
int a[maxn];
int mx[maxn],mn[maxn][26];
int log_2[maxn];
int query(int l,int r){
    int i=log_2[r-l+1];
    return min(mn[l][i],mn[r-(1<<i)+1][i]);
}
int main(){
    int i,j,n,m;
    int ans=0;
    // freopen("test.in","r",stdin);
    scanf("%d",&n);
    for(i=1;i<=n;++i) scanf("%d",&a[i]);
    for(i=1;i<=n;++i) mn[i][0]=a[i];
    log_2[1]=0;
    for(i=2;i<=n;++i) log_2[i]=log_2[i>>1]+1;
    for(i=1;i<=log_2[n];++i){
        for(j=1;j+(1<<i)-1<=n;++j){
            mn[j][i]=min(mn[j][i-1],mn[j+(1<<i-1)][i-1]);
        }
    }
    for(i=1;i<=n;++i) mx[i]=max(mx[i-1],a[i]);
    for(i=1;i<=n;++i){
        int flag=1;
        for(j=1;j<=n;j+=i){
            int l=j,r=min(j+i-1,n);
            int t=query(l,r);
            if(t<mx[j-1]){
                flag=0;
                break;
            }
        }
        ans+=flag;
    }
    printf("%d",ans);
    return 0;
}

F. Art for Last

简单题。

注意到结果只与集合有关,与顺序无关,所以我们可以先排好序。

然后观察到最优结果必然是取连续一段(排序后的数组),最大差值就是区间头尾之差,最小差值一定在相邻两个元素间取到。

所以做下差分,在差分数组里找区间最小值即可。

至于为啥一定取连续区间,反证法很好证。

时间复杂度\(\Theta(n log n)\)。

代码:

点击查看代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define maxn 500010
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
int a[maxn];
int v[maxn<<2],l[maxn<<2],r[maxn<<2];
void update(int x){
    v[x]=min(v[x<<1],v[x<<1|1]);
}
void build(int x,int left,int right){
    l[x]=left,r[x]=right;
    if(left==right){
        v[x]=abs(a[left+1]-a[left]);
        return;
    }
    int mid=left+right>>1;
    build(x<<1,left,mid);
    build(x<<1|1,mid+1,right);
    update(x);
}
int query(int x,int left,int right){
    int r1=inf,r2=inf;
    if(l[x]>=left&&r[x]<=right) return v[x];
    int mid=l[x]+r[x]>>1;
    if(left<=mid) r1=query(x<<1,left,right);
    if(right>mid) r2=query(x<<1|1,left,right);
    return min(r1,r2);
}
int main(){
    int i,j,n,T,flag,k;
    ll ans=-1;
    // freopen("test.in","r",stdin);
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;++i){
        scanf("%d",&a[i]);
    }
    sort(a+1,a+n+1);
    for(i=2;i<=n;++i){
        if(a[i]==a[i-1]){
            printf("0");
            return 0;
        }
    }
    build(1,1,n-1);
    for(i=k;i<=n;++i){
        ll val=(ll)(a[i]-a[i-k+1])*(ll)query(1,i-k+1,i-1);
        if(ans<0) ans=val;
        ans=min(ans,val);
    }
    printf("%lld",ans);
    return 0;
}

标签:log,河南省,复杂度,int,maxn,补题,2023,include,define
From: https://www.cnblogs.com/landmine-sweeper/p/17410700.html

相关文章

  • 2023.5.17
    1题目描述:定义一个时间类,小时和分钟是其两个私有成员数据。输入一个起始时间和一个结束时间(起始时间早于结束时间),通过运算符重载-(减号),计算这两个时间相隔多少分钟。说明:这两个时间在同一天之内,且采用24小时计时分式,即从00:00-23:59。23输入格式:测试输入包含若干......
  • 【愚公系列】2023年05月 .NET CORE工具案例-对象映射Master的使用
    (文章目录)前言对象映射框架Master可以帮助开发人员将对象映射到数据库,以进行数据持久化。它还可以支持ORM(对象关系映射),以及其他数据库技术,比如存储过程。它可以帮助开发人员更快、更有效地完成数据库操作。Master官网:https://github.com/MapsterMapper/Mapster一、对象映射m......
  • 2023-05-17:一个正整数如果能被 a 或 b 整除,那么它是神奇的。 给定三个整数 n , a , b
    2023-05-17:一个正整数如果能被a或b整除,那么它是神奇的。给定三个整数n,a,b,返回第n个神奇的数字。因为答案可能很大,所以返回答案对10^9+7取模后的值。输入:n=4,a=2,b=3。输出:6。答案2023-05-17:过程描述:1.计算a和b的最小公倍数lcm。2.初始化......
  • 考研学习 | 每日回顾(2023年5月15日)
    昨天的考研数学笔记常用的极限两原则:拆分之后的所有式子都要有极限且只能在乘除法之间使用等价无穷小替换如果一个部分无法直接被化简计算,就尝试整体代换反三角函数arcsinx和arccosx的关系遇到三角函数问题时要知道:不同的三角函数之间可以相互转换......
  • 2023-05-17 刷题
    算法题目1:【Mid】47.全排列II思路分析:将原问题转换成子问题,先不考虑重复元素,例如P{1,2,3}={"1"+P{2,3},"2"+P{1,3},"3"+P{1,2}}。之后再考虑重复元素。怎么枚举?枚举每个位置可以填哪些数。【这种枚举方式能保证字典序,除此外,还有一种,枚举每个数可以放到哪个位置上,......
  • 考研学习 | 每日回顾(2023年5月17日)
    昨天的考研数学笔记求解偏导数的时候一定要清楚当前谁是自变量:文内有小技巧求偏导时,函数的第一部分变量用1表示,第二部分变量用2表示......
  • 考研学习 | 每日回顾(2023年5月13日)
    昨天的考研数学笔记只对x求偏导时,y的值可以提前代入y不一定就是x的函数......
  • 2023 湖北ccpc
    F.InverseManacher题意:给定回文半径数组,构造回文串(只包含a,b)分析:题目保证一定合法,我们考虑每个'|'位置上的回文半径如果r=1:说明前一个位置与后一个位置上的字符不同如果r>1:说明前一段位置与后一段位置回文,则要保证前后位置上的字符相同实现:#include<bits/std......
  • YACS 2023年5月月赛 甲组 T1 子集和(六) 题解
    YACS老师说这是道分治,但就不告诉我怎么做,我硬是用线段树卡了过去...特别解气的是把AC图片发了过去(我就是在YACS上的编程课)莫队好了说点正经的,看到是谁谁谁的倍数就能想到DP,状态设计也很水啦!设f[i]为当前考虑到的区间内,子集和%k=i的数量。新加入一个元素时,循环0~......
  • 2022-2023年大二上mysql学习汇总
    CRUD等操作(DDL、DML、DQL)权限操作:createuser用户名@"localhost或%" identifiedby'密码'  showgrantsfor用户名@主机名 grant权限列表(all/insert/delete/select等)on库名(*).表名(*)to用户名@主机名  remove与授予一样函数:内置(后面加as......