CF补题第二天

news2024/9/28 22:47:30

题1

先来一道最短路热身

题目描述:

思路:第一眼SPFA,结果直接超时,正解思路:每一条边只走一次,那么我们找出不同的连通块,然后拓扑排序求最短路(因为无环),拓扑排序时对于每个连通块内部跑dij

代码如下:

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int N=26000,M=3*1e6+10,INF=0x3f3f3f3f;
typedef pair<int,int> PII;

int h[N],e[M],ne[M],idx,w[M];

int id[N],vis[N];
vector<int>block[N];
int in[N];
int dist[N];
queue<int>q;
int cnt;
void add(int a, int b, int c){
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

void dfs(int u, int cnt){
    id[u]=cnt;
    block[cnt].push_back(u);
    for(int i=h[u]; ~i; i=ne[i]){
        int v=e[i];
        if(id[v])continue;
        dfs(v,cnt);
    }
}

void dij(int u){
    priority_queue<PII,vector<PII>,greater<PII>>heap;
    for(auto v:block[u])heap.push({dist[v],v});

    while(!heap.empty()){
        auto [x,y]=heap.top();
        heap.pop();
        if(vis[y])continue;
        vis[y]=true;
        for(int i=h[y]; ~i; i=ne[i]){
            int v=e[i];
            int val=w[i];
            if(id[y]!=id[v] && --in[id[v]]==0)q.push(id[v]);
            if(dist[v]>dist[y]+val){
                dist[v]=dist[y]+val;
                if(id[y]==id[v]){
                    heap.push({dist[v],v});
                }
            }
        }
    }
}

void topsort(int s){
    memset(dist,0x3f,sizeof dist);
    dist[s]=0;
    for(int i=1; i<cnt; i++){
        if(!in[i])q.push(i);
    }

    while(!q.empty()){
        int t=q.front();
        q.pop();
        dij(t);
    }
}


int main(){
    memset(h,-1,sizeof h);
    int n,num1,num2,s;
    cin>>n>>num1>>num2>>s;

    for(int i=0; i<num1; i++){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);add(b,a,c);
    }
    cnt=1;
    for(int i=1; i<=n; i++){
        if(!id[i]){
            dfs(i,cnt);
            cnt++;
        }
    }

    while(num2--){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        in[id[b]]++;
    }

    topsort(s);
    for(int i=1; i<=n; i++){
        if(dist[i]>=INF/2)cout<<"NO PATH"<<endl;
        else cout<<dist[i]<<endl;
    }
}

题2

题目链接:https://codeforces.com/contest/2019/problem/C

思路:贪心O(1)check,如果avg>=mx,那么差值最多为1,否则至少补偿len*mx-sum;

代码如下:

#include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using namespace std;
void solve() {
    int n;
    i64 k;
    cin>>n>>k;
    i64 maxnum=0;
    i64 sum=0;
    for(int i=0; i<n; i++){
        i64 t;
        cin>>t;
        sum+=t;
        maxnum=max(maxnum,t);
    }
    int ans=1;
    for(int len=1; len<=n; len++){
        i64 avg=(sum+len-1)/len;
        if(avg>=maxnum && k>=(avg*len-sum)){
            ans=len;
        }
        else if(avg<maxnum && k>=maxnum*len-sum)ans=len;
    }
    cout<<ans<<endl;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int t;
    std::cin >> t;
    
    while (t--) {
        solve();
    }
    
    return 0;
}

题3

题目链接:https://codeforces.com/contest/2019/problem/E

思路:实际上是考虑一个点的贡献,然后前缀优化O(n)处理。剩下的就是跑树而已;

代码如下:

#include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using namespace std;
void solve() {
    int n;
    cin>>n;
    vector<int>e[n+1];
    vector<int>dep(n+1,0),deps(n+2,0),lastdep(n+1,0),sum(n+2,0);
    vector<int>siz(n+1,0);
    for(int i=0; i<n-1; i++){
        int a,b;
        cin>>a>>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    
    function<void(int,int)> dfs=[&](int u, int fa)->void{
        siz[u]=1;
        for(auto v:e[u]){
            if(v==fa)continue;
            dfs(v,u);
            siz[u]+=siz[v];
        }
    };
    int maxlen=0;
  function<void(int,int)> dfs1=[&](int u, int fa)->void{
        dep[u]=dep[fa]+1;
        maxlen=max(maxlen,dep[u]);
        deps[dep[u]]+=siz[u]-1;
        lastdep[u]=dep[u];
        for(auto v:e[u]){
            if(v==fa)continue;
            dfs1(v,u);
            lastdep[u]=max(lastdep[v],lastdep[u]);
        }
        sum[lastdep[u]+1]++;
    };
    dfs(1,0);
    dfs1(1,0);
    for(int i=1; i<=n+1; i++){
        sum[i]+=sum[i-1];
    }
    int res=1e9;
    for(int i=1; i<=maxlen; i++){
        //cout<<deps[i]<<endl;
        res=min(res,deps[i]+sum[i]);
    }
    cout<<res<<endl;
    
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int t;
    std::cin >> t;
    
    while (t--) {
        solve();
    }
    
    return 0;
}

题4

题目链接:https://codeforces.com/contest/2019/problem/D

思路:预处理左右最短时间,枚举每个点,暴力check

代码如下:

#include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using namespace std;
const int inf=1e9;
void solve() {
    int n;
    cin>>n;
    vector<int>a(n+2);
    for(int i=1; i<=n; i++)cin>>a[i];
    vector<pair<int,int>>l(n+2);
    vector<pair<int,int>>r(n+2);
    l[1]={inf,0};
    r[n]={inf,n+1};
    for(int i=2; i<=n; i++){
        int dis=l[i-1].first;
        if(dis>a[i-1]){
            l[i]={a[i-1],i-1};
        }else l[i]=l[i-1];
    }
    for(int i=n-1; i>=1; i--){
        int dis=r[i+1].first;
        if(dis>a[i+1]){
            r[i]={a[i+1],i+1};
        }else r[i]=r[i+1];
    }
    auto check=[&](int mid)->bool{
        int lp=mid,rp=mid;
        int times=1;
        while(true){
            if(times==n){
                break;
            }
            if(l[lp].first<r[rp].first ){
                times+=lp-l[lp].second;
                if(times>l[lp].first)return false;
                lp=l[lp].second;
            }
            else{
                times+=r[rp].second-rp;
                if(times>r[rp].first)return false;
                rp=r[rp].second;
            }
        }
        return true;
        
    };
    int ans=0;
    for(int i=1; i<=n; i++){
        if(check(i))ans++;
        //cout<<endl;
    }
    cout<<ans<<endl;
    
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int t;
    std::cin >> t;
    
    while (t--) {
        solve();
    }
    
    return 0;
}

题5

题目链接:https://codeforces.com/contest/1996/problem/F

思路:实际上对于最大值,他一定是有某个数作为分割点,我们考虑二分这个数,如果这个数上面的res>k那么这个数一定小了,所以l=mid+1;否则r=mid;我们求出第一个res<=k的位置就是答案

代码如下:

#include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using namespace std;
const int inf=1e9;
void solve() {
    int n,k;;
    cin>>n>>k;
    vector<i64>a(n),b(n);
    i64 mx=0;
    for(int i=0; i<n; i++){
        cin>>a[i];
        mx=max(mx,a[i]);
    }
    for(int i=0; i<n; i++){
        cin>>b[i];
    }
    i64 l=0,r=mx;
    i64 sum=0;
    auto check=[&](i64 mid)->bool{
        i64 cnt=0;
        i64 res=0;
        for(int i=0; i<n; i++){
            if(a[i]>=mid){
                i64 t=(a[i]-mid+b[i]-1)/b[i];
                res+=t;
                cnt+=((a[i]-mid)%b[i]==0);
            }
        }
        return k>=res;
    };
    while(r>l){
        i64 mid=l+r>>1;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    i64 mid=l;
    i64 cnt=0;
    i64 res=0;
//cout<<mid<<endl;
    for(int i=0; i<n; i++){
        if(a[i]>=mid){
            i64 t=(a[i]-mid+b[i]-1)/b[i];
            res+=t;
            cnt+=((a[i]-mid)%b[i]==0);
            sum+=t*a[i]-(t-1)*t/2*b[i];
        }
    }
    sum+=(k-res)*l;
    cout<<sum<<endl;
    
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int t;
    std::cin >> t;
    
    while (t--) {
        solve();
    }
    
    return 0;
}

总结:思路看起来很简单,但是我自己想却需要想1h左右,这是打CF的第30天,分数现在为1278,下一个月再接再励,先上1600。后面也会记录我在工程方面的学习。当然这些总结只是对我自己而写的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2175009.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

有问题未解决(9.28)

#include <stdio.h> int main() {int a 1;int b 2;int c 3;int arr[] { a,b,c };arr[0] 10;printf("%d\n", a);//打印结果为1&#xff1b;return 0; } 颠覆认知了&#xff0c;或许也没有颠覆 arr是一个int类型的数组&#xff0c;他存的就是一个数&…

Android——ContentObserver监听短信

概述 内容观察器ContentObserver给目标内容注册一个观察器&#xff0c;目标内容的数据一旦发生变化&#xff0c;观察器规定好的动作马上触发&#xff0c;从而执行开发者预先定义的代码。 思路 注册一个监听 getContentResolver().registerContentObserver(uri, true, mObser…

QT+ESP8266+STM32项目构建三部曲三--QT从环境配置到源程序的解析

一、阿里云环境配置 大家在编写QT连接阿里云的程序之前&#xff0c;先按照下面这篇文章让消息可以在阿里云上顺利流转 QTESP8266STM32项目构建三部曲二--阿里云云端处理之云产品流转-CSDN博客文章浏览阅读485次&#xff0c;点赞7次&#xff0c;收藏4次。创建两个设备&#xff…

找不到msvcp110.dll怎么办,总结6种解决msvcp110.dll的方法

在电脑使用过程中&#xff0c;我们可能会遇到各种各样的问题&#xff0c;其中之一就是系统提示某个文件丢失。msvcp110.dll丢失是一个比较常见的问题&#xff0c;它可能导致某些程序无法正常运行。那么&#xff0c;如何解决这个问题呢&#xff1f;本文将详细介绍6种修复msvcp11…

手把手教你用PyTorch从零训练自己的大模型(非常详细)零基础入门到精通,收藏这一篇就够了

长按关注《AI科技论谈》 LLM是如今大多数AI聊天机器人的核心基础&#xff0c;例如ChatGPT、Gemini、MetaAI、Mistral AI等。这些LLM背后的核心是Transformer架构。 本文介绍如何一步步使用PyTorch从零开始构建和训练一个大型语言模型&#xff08;LLM&#xff09;。该模型以Tra…

OpenHarmony标准系统上实现对rk系列芯片NPU的支持(npu使用)

在上篇文章中&#xff0c;我们学习了移植rk的npu驱动到OpenHarmony提供的内核。本文我们来学习如何在OpenHarmony标准系统rk系列芯片如何使用npu OpenHarmony RK系列芯片运行npu测试用例 在移植npu驱动到OpenHarmony之后&#xff0c;来运行npu样例进行简单测试 1.O 测试准备…

【球形空间产生器】

题目 代码 #pragma GCC optimize(3) #include <bits/stdc.h> using namespace std; const double eps 1e-6; const int N 12; double g[N][N]; double ss[N]; int n; void gauss() {int c, r, t;for(c 1, r 1; c < n; c){int t r;for(int i r1; i < n; i)i…

Wayfair封号的常见原因及解决方案解析

近期关于Wayfair账号封禁的问题引发了广泛讨论。许多用户报告称&#xff0c;他们的Wayfair账户被突然封禁&#xff0c;这一现象不仅影响了用户的购物体验&#xff0c;也对Wayfair的品牌形象造成了一定的冲击。本文将深入探讨Wayfair封号的原因&#xff0c;并提出相应的解决方案…

【SpringCloud】服务注册/服务发现-Eureka

服务注册/服务发现-Eureka 1. 背景1.1 问题描述1.2 解决思路1.3 什么是注册中⼼1.4 CAP理论1.5 常⻅的注册中⼼ 2. Eureka 介绍3. 搭建Eureka Server 1. 背景 1.1 问题描述 上个章节的例⼦中可以看到, 远程调⽤时, 我们的URL是写死的 String url "http://127.0.0.1:90…

Flink CDC实时同步MySQL到Doris

文章目录 1.开启Flink集群2.MySQL准备数据并开启Binlog3.FlinkCDC 提交任务到集群任务提交同步变更库表迁移 问题总结 Apache Flink CDC&#xff08;Change Data Capture&#xff09;是一个用于捕获和跟踪数据库更改的技术&#xff0c;它能够实时地从数据库中获取数据变更&…

★ C++进阶篇 ★ map和set

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;我将继续和大家一起学习C进阶篇第四章----map和set ~ ❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️ 澄岚主页&#xff1a;椎名澄嵐-CSDN博客 C基础篇专栏&#xff1a;★ C基础篇 ★_椎名澄嵐的博客-CSDN博…

AVLTree【c++实现】

目录 AVL树1.AVL树的概念2.AVLTree节点的定义3.AVLTree的插入4.AVLTree的旋转4.1左单旋4.2右单旋4.3左右双旋4.4右左双旋 5.AVLTree的验证6.AVLTree的性能 AVL树 AVLTree的代码实现连接&#xff1a; AVLTree 代码链接 1.AVL树的概念 学习了二叉搜索树之后&#xff0c;我们知…

18年408数据结构

第一题&#xff1a; 解析&#xff1a;这道题很简单&#xff0c;按部就班的做就可以了。 画出S1&#xff0c;S2两个栈的情况&#xff1a; S1: S2: 2 3 - 8 * 5 从S1中依次弹出两个操作数2和3&a…

甄选范文“论企业应用系统的数据持久层架构设计”,软考高级论文,系统架构设计师论文

论文真题 数据持久层(Data Persistence Layer)通常位于企业应用系统的业务逻辑层和数据源层之间,为整个项目提供一个高层、统一、安全、并发的数据持久机制,完成对各种数据进行持久化的编程工作,并为系统业务逻辑层提供服务。它能够使程序员避免手工编写访问数据源的方法…

IDEA 高版本创建 Spring Boot 项目选不到 java 8

一、场景分析 现在高版本的 IDEA&#xff0c;创建 Spring Boot 项目时常常会选不到 Java 8&#xff1a; 直接使用 Java 17 新建项目&#xff0c;又会报错&#xff1a; Selected version of Java 17 is not supported by the project SDK 1.8. Either choose a lower version o…

Linux增加一个回收站功能(实用功能)

在linux中,默认是没有回收站的概念的,文件被删除之后,就没有了,很难进行恢复,本章教程,教你如何在linux中安装一个回收站功能,让你的文件即使删掉了,也有即使找回来。 一、安装插件 需要注意的是, python版本需要大于3.8,否则安装之后可能无法使用。 1、下载插件 ht…

基于Qt的多功能串口通信工具分享:实时数据收发与波形绘制

需要工程源码请私信 基于 Qt 框架开发的多功能串口通信工具&#xff0c;旨在为用户提供稳定、流畅的串口数据收发体验。该工具不仅支持基本的串口通信功能&#xff0c;还集成了定时发送、多线程数据处理、粘包问题解决、实时波形绘制等多种高级功能。通过使用 QSerialPort 进行…

录屏小白福音!三款神器助你轻松上手

生活工作中&#xff0c;需要借助录屏功能越来越家常便饭了&#xff0c;选择录屏软件时&#xff0c;主要考虑的是软件的易用性、功能以及用户评价等因素。以下是如何进行录屏的步骤&#xff0c;以及推荐的四个录屏软件的使用说明&#xff1a;关于如何录屏的步骤操作&#xff0c;…

使用 PowerShell 命令更改 RDP 远程桌面端口(无需修改防火墙设置)

节选自原文&#xff1a;Windows远程桌面一站式指南 | BOBO Blog 原文目录 什么是RDP&#xfffc;开启远程桌面 检查系统版本启用远程桌面连接Windows 在Windows电脑上在MAC电脑上在Android或iOS移动设备上主机名连接 自定义电脑名通过主机名远程桌面使用Hosts文件自定义远程主…

(undone) MIT6.824 Lecture1 笔记

参考1MIT课程视频&#xff1a;https://www.bilibili.com/video/BV16f4y1z7kn/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 参考2某大佬笔记&#xff1a;https://ashiamd.github.io/docsify-notes/#/study/%E5%88%86%E5%B8%83%…