20231013比赛总结

2023-10-17 04:20
文章标签 总结 比赛 20231013

本文主要是介绍20231013比赛总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

反思

A

s b sb sb 题,不多说

B

感觉不太好像,也不好证,不过发现了自己斜率优化不熟练的缺点

C

深刻认识到了自己的菜,感觉很典的题却连部分分都不会做

D

不说了, n f l s nfls nfls ∗ ∗ ** ,放大树分块题,狗都不补

题解

A

不说了,直接 s e g m e n t − t r e e segment-tree segmenttree

#include <bits/stdc++.h>
using namespace std;
const int N=200100;
int n,q,a[N];
inline int read(){int FF=0,RR=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;return FF*RR;
}
struct SegmentTree{int seg[N<<2];void build(int l,int r,int x,int type){if(l==r){ seg[x]=(l&1)==type?a[l]:0;return;}int mid=(l+r)>>1;build(l,mid,x<<1,type),build(mid+1,r,x<<1^1,type);seg[x]=seg[x<<1]^seg[x<<1^1];}void modify(int l,int r,int x,int pos,int v){if(l==r){ seg[x]=v;return;}int mid=(l+r)>>1;if(mid>=pos) modify(l,mid,x<<1,pos,v);else modify(mid+1,r,x<<1^1,pos,v);seg[x]=seg[x<<1]^seg[x<<1^1];}int query(int l,int r,int x,int L,int R){if(L<=l&&r<=R) return seg[x];int mid=(l+r)>>1;if(mid>=L&&mid<R) return query(l,mid,x<<1,L,R)^query(mid+1,r,x<<1^1,L,R);if(mid>=L) return query(l,mid,x<<1,L,R);return query(mid+1,r,x<<1^1,L,R);}
}sg0,sg1;
int main(){freopen("orange.in","r",stdin);freopen("orange.out","w",stdout);n=read(),q=read();for(int i=1;i<=n;i++) a[i]=read();sg0.build(1,n,1,0),sg1.build(1,n,1,1);while(q--){int op=read(),x=read(),y=read();if(op==1){if(x&1) sg1.modify(1,n,1,x,y);else sg0.modify(1,n,1,x,y);}else{if((y-x+1)&1){if(x&1) printf("%d\n",sg1.query(1,n,1,x,y));else printf("%d\n",sg0.query(1,n,1,x,y));}else puts("0");}}fprintf(stderr,"%d ms\n",int(1e3*clock()/CLOCKS_PER_SEC));return 0;
}

B

放在 T 2 T2 T2 感觉很困难
考虑一个构造做法是:
我们把 a i a_i ai 从大到小排序,如果我们砸开的椰子集合为 { b 1 , . . . , b m } \{b_1,...,b_m\} {b1,...,bm},那么最优的最坏情况下需要砸的次数为 ∑ i = 1 m ( b i − b i − 1 ) a b i \sum\limits_{i=1}^{m}(b_i-b_{i-1})a_{b_i} i=1m(bibi1)abi
然后就可以列出朴素的 d p dp dp,然后用斜率优化,时间复杂度为 O ( n m ) O(nm) O(nm)
我发现自己的斜率优化很不熟练,感觉只会板子
当在下凸壳上查询点递减,只要用栈就可以了,而不是记录 h e a d , t a i l head,tail head,tail 指针
为什么这个构造是对的话可以考虑每次我们的目标是砸开某一个椰子 x x x ,那么最坏情况就是前面的所有椰子都被砸一遍,所以我们取阈值 a x a_x ax 最优

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2100;
int a[N],f[N][N];
int q[N],tt;
inline int read(){int FF=0,RR=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;return FF*RR;
}
void work(){int n=read(),m=read();for(int i=1;i<=n;i++) a[i]=read();sort(a+1,a+n+1,greater<int>());memset(f,0x3f,sizeof(f));int inf=f[0][0];f[0][0]=0;for(int j=1;j<=m;j++){q[1]=0,tt=1;for(int i=1;i<=n;i++){while(tt>=2&&f[q[tt]][j-1]-f[q[tt-1]][j-1]>(__int128)a[i]*(q[tt]-q[tt-1])) tt--;int k=q[tt];if(f[k][j-1]!=inf) f[i][j]=f[k][j-1]+a[i]*(i-k);while(tt>=2&&(__int128)(f[q[tt]][j-1]-f[q[tt-1]][j-1])*(i-q[tt])>(__int128)(f[i][j-1]-f[q[tt]][j-1])*(q[tt]-q[tt-1])) tt--;q[++tt]=i;}}int ans=inf;for(int i=1;i<=n;i++) ans=min(ans,f[i][m]);printf("%lld\n",ans);
}
signed main(){freopen("protect.in","r",stdin);freopen("protect.out","w",stdout);int T=read();while(T--) work();fprintf(stderr,"%d ms\n",int64_t(1e3*clock()/CLOCKS_PER_SEC));return 0;
}

C

感觉是一道很经典的题
我们首先考虑 n m l o g nmlog nmlog 怎么做
先把每一件装备从大到小排序
我们可以用堆来维护所有可以的当前最大选择,不妨令选择为 ( c 1 , c 2 , . . . , c n ) (c_1,c_2,...,c_n) (c1,c2,...,cn)
考虑如何拓展新的方案,我们可以把任意一个 c i + 1 c_i+1 ci+1,然后把这个选择放进去,要注意去重,时间复杂度 O ( n m l o g n ) O(nmlogn) O(nmlogn)

考虑拓展的形态是一个 D A G DAG DAG,这样会导致去重的复杂度瓶颈
我们考虑把 D A G DAG DAG 变成一棵树,即给每个状态钦定唯一的转移顺序
我们令三元组 ( v a l , p , c ) (val,p,c) (val,p,c) 表示权值和为 v a l val val,现在修改到第 p p p 个,后面都选的是第 1 1 1 个,第 p p p 个选的是第 c c c 个,且后面不修改 < p <p <p 的状态
考虑转移:

  1. → ( v a l ′ , p , c + 1 ) \to (val',p,c+1) (val,p,c+1)
  2. c > 1 c>1 c>1 时, → ( v a l ′ , p ′ , 2 ) \to (val',p',2) (val,p,2)

思考一下可以发现这样可以不重不漏的表示出所有的状态(感觉不是见过很难想)
考虑这样转移仍然是 O ( n m l o g ) O(nmlog) O(nmlog)
不难想到如下的等价转移方式:

  1. → ( v a l ′ , p , c + 1 ) \to (val',p,c+1) (val,p,c+1)
  2. c > 1 c>1 c>1 时, → ( v a l ′ , p + 1 , 2 ) \to (val',p+1,2) (val,p+1,2)
  3. c = 2 c=2 c=2 时, → ( v a l ′ , p + 1 , 2 ) \to (val',p+1,2) (val,p+1,2) 且把 p p p c c c 变为 1 1 1

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

#include <bits/stdc++.h>
#define pb push_back
#define int long long
using namespace std;
const int N=300100,P=20190816170251;
struct Node{int val,p,x;bool operator <(const Node &o)const{ return val<o.val;}
};
int n,m,ans[N];
priority_queue<Node> pq;
vector<int> G[N];
inline int read(){int FF=0,RR=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;return FF*RR;
}
bool cmp(vector<int> &A,vector<int> &B){ return A[1]-A[0]>B[1]-B[0];}
signed main(){freopen("contain.in","r",stdin);freopen("contain.out","w",stdout);n=read(),m=read();int res=0;for(int i=1;i<=n;i++){int cnt=read();if(cnt==1) res+=read(),i--,n--;else{while(cnt--) G[i].pb(read());sort(G[i].begin(),G[i].end(),greater<int>());}}sort(G+1,G+n+1,cmp);int mx=res;for(int i=1;i<=n;i++) mx+=G[i][0];pq.push({mx,1,1});for(int i=1;i<=m;i++){Node cur=pq.top();ans[i]=cur.val;pq.pop();if(cur.x<G[cur.p].size()){pq.push({cur.val+G[cur.p][cur.x]-G[cur.p][cur.x-1],cur.p,cur.x+1});}if(cur.p<n){if(cur.x>1) pq.push({cur.val+G[cur.p+1][1]-G[cur.p+1][0],cur.p+1,2});if(cur.x==2) pq.push({cur.val+G[cur.p+1][1]-G[cur.p+1][0]+G[cur.p][0]-G[cur.p][1],cur.p+1,2});}}// for(int i=1;i<=m;i++) cout<<ans[i]<<' ';cout<<'\n';int ANS=0;for(int i=m,pw=1;i>=1;i--,pw=pw*23333%P) ANS=(ANS+(__int128_t)pw*ans[i]%P)%P;printf("%lld\n",ANS);fprintf(stderr,"%d ms\n",int64_t(1e3*clock()/CLOCKS_PER_SEC));return 0;
}

这篇关于20231013比赛总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/222909

相关文章

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

Nginx Location映射规则总结归纳与最佳实践

《NginxLocation映射规则总结归纳与最佳实践》Nginx的location指令是配置请求路由的核心机制,其匹配规则直接影响请求的处理流程,下面给大家介绍NginxLocation映射规则... 目录一、Location匹配规则与优先级1. 匹配模式2. 优先级顺序3. 匹配示例二、Proxy_pa

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

MySQL基本查询示例总结

《MySQL基本查询示例总结》:本文主要介绍MySQL基本查询示例总结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Create插入替换Retrieve(读取)select(确定列)where条件(确定行)null查询order by语句li

Linux区分SSD和机械硬盘的方法总结

《Linux区分SSD和机械硬盘的方法总结》在Linux系统管理中,了解存储设备的类型和特性是至关重要的,不同的存储介质(如固态硬盘SSD和机械硬盘HDD)在性能、可靠性和适用场景上有着显著差异,本文... 目录一、lsblk 命令简介基本用法二、识别磁盘类型的关键参数:ROTA查询 ROTA 参数ROTA

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

Windows Docker端口占用错误及解决方案总结

《WindowsDocker端口占用错误及解决方案总结》在Windows环境下使用Docker容器时,端口占用错误是开发和运维中常见且棘手的问题,本文将深入剖析该问题的成因,介绍如何通过查看端口分配... 目录引言Windows docker 端口占用错误及解决方案汇总端口冲突形成原因解析诊断当前端口情况解