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

相关文章

Kubernetes常用命令大全近期总结

《Kubernetes常用命令大全近期总结》Kubernetes是用于大规模部署和管理这些容器的开源软件-在希腊语中,这个词还有“舵手”或“飞行员”的意思,使用Kubernetes(有时被称为“... 目录前言Kubernetes 的工作原理为什么要使用 Kubernetes?Kubernetes常用命令总

Python中实现进度条的多种方法总结

《Python中实现进度条的多种方法总结》在Python编程中,进度条是一个非常有用的功能,它能让用户直观地了解任务的进度,提升用户体验,本文将介绍几种在Python中实现进度条的常用方法,并通过代码... 目录一、简单的打印方式二、使用tqdm库三、使用alive-progress库四、使用progres

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Java向kettle8.0传递参数的方式总结

《Java向kettle8.0传递参数的方式总结》介绍了如何在Kettle中传递参数到转换和作业中,包括设置全局properties、使用TransMeta和JobMeta的parameterValu... 目录1.传递参数到转换中2.传递参数到作业中总结1.传递参数到转换中1.1. 通过设置Trans的

C# Task Cancellation使用总结

《C#TaskCancellation使用总结》本文主要介绍了在使用CancellationTokenSource取消任务时的行为,以及如何使用Task的ContinueWith方法来处理任务的延... 目录C# Task Cancellation总结1、调用cancellationTokenSource.

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000